1529690b6SJiao Xianjun<!-- 2529690b6SJiao XianjunAuthor: Xianjun Jiao 3529690b6SJiao XianjunSPDX-FileCopyrightText: 2022 UGent 4529690b6SJiao XianjunSPDX-License-Identifier: AGPL-3.0-or-later 5529690b6SJiao Xianjun--> 6529690b6SJiao Xianjun 7529690b6SJiao XianjunOne super power of the openwifi platform is "**Full Duplex**" which means that openwifi baseband can receive its own TX signal. 87eea2988SXianjun JiaoThis makes the IQ sample, WiFi packet and CSI self loopback test possible. Reading the normal [IQ sample capture app note](iq.md) and [CSI radar app note](radar-self-csi.md) will help if you have issue or want to understand openwifi side channel (for IQ and CSI) deeper. 9529690b6SJiao Xianjun 10529690b6SJiao Xianjun 11529690b6SJiao Xianjun[[IQ self loopback quick start](#IQ-self-loopback-quick-start)] 12529690b6SJiao Xianjun[[Check the packet loopback on board](#Check-the-packet-loopback-on-board)] 137eea2988SXianjun Jiao[[IQ self loopback config](#IQ-self-loopback-config)] 147eea2988SXianjun Jiao[[CSI FPGA self loopback quick start](#CSI-FPGA-self-loopback-quick-start)] 15529690b6SJiao Xianjun 16529690b6SJiao Xianjun## IQ self loopback quick start 17a066622eSWei.Li(Please replace the IQ length **8187** by **4095** if you use low end FPGA board: zedboard/adrv9464z7020/antsdr/zc702/sdrpi) 18529690b6SJiao Xianjun- Power on the SDR board. 19529690b6SJiao Xianjun- Put the Tx and Rx antenna as close as possible. 20529690b6SJiao Xianjun- Connect a computer to the SDR board via Ethernet cable. The computer should have static IP 192.168.10.1. Open a terminal on the computer, and then in the terminal: 21529690b6SJiao Xianjun ``` 22b6f91403Sredfast00 # ssh into the SDR board, password: openwifi 23529690b6SJiao Xianjun ssh [email protected] 24529690b6SJiao Xianjun cd openwifi 25b6f91403Sredfast00 # Bring up the openwifi NIC sdr0 26529690b6SJiao Xianjun ./wgd.sh 27b6f91403Sredfast00 28b6f91403Sredfast00 # Setup monitor mode in WiFi channel 44. You should find a channel as clean as possible in your location. Note that some channels don't work, so stick to 44 or 48 for now. 29529690b6SJiao Xianjun ./monitor_ch.sh sdr0 44 30b6f91403Sredfast00 31b6f91403Sredfast00 # Turn off CCA by setting a very high threshold that make the CSMA engine always think the channel is idle (no incoming signal is higher than this threshold) 32b6f91403Sredfast00 ./sdrctl dev sdr0 set reg xpu 8 1000 33b6f91403Sredfast00 34b6f91403Sredfast00 # Load side channel kernel module with buffer lenght of 8187 (replace this with 4095 when using low end FPGA board) 35529690b6SJiao Xianjun insmod side_ch.ko iq_len_init=8187 36b6f91403Sredfast00 37b6f91403Sredfast00 # Set 100 to register 11. It means the pre trigger length is 100, so we mainly capture IQ after trigger condition is met 3805506cbaSJiao Xianjun ./side_ch_ctl wh11d100 39b6f91403Sredfast00 # Set 16 to register 8 -- set trigger condition to phy_tx_started signal from openofdm tx core 40529690b6SJiao Xianjun ./side_ch_ctl wh8d16 41b6f91403Sredfast00 # Unmute the baseband self-receiving to receive openwifi own TX signal/packet -- important for self loopback! 42529690b6SJiao Xianjun ./sdrctl dev sdr0 set reg xpu 1 1 43b6f91403Sredfast00 # Set the loopback mode to over-the-air 44dbcf06d1SJiao Xianjun ./side_ch_ctl wh5h0 45b6f91403Sredfast00 # Relay the FPGA IQ capture to the host computer that will show the captured IQ later on) 46529690b6SJiao Xianjun ./side_ch_ctl g0 47529690b6SJiao Xianjun ``` 48529690b6SJiao Xianjun You should see on outputs like: 49529690b6SJiao Xianjun ``` 50529690b6SJiao Xianjun loop 22848 side info count 0 51529690b6SJiao Xianjun loop 22912 side info count 0 52529690b6SJiao Xianjun ... 53529690b6SJiao Xianjun ``` 54529690b6SJiao Xianjun Now the count is always 0, because we haven't instructed openwifi to send packet for loopback test. 55529690b6SJiao Xianjun 56529690b6SJiao Xianjun- Leave above ssh session untouched. Open a new ssh session to the board from your computer. Then run on board: 57529690b6SJiao Xianjun ``` 58529690b6SJiao Xianjun cd openwifi/inject_80211/ 59529690b6SJiao Xianjun make 60b6f91403Sredfast00 # Build our example packet injection program 61529690b6SJiao Xianjun ./inject_80211 -m n -r 5 -n 1 sdr0 62b6f91403Sredfast00 # Inject one packet to openwifi sdr0 NIC 63529690b6SJiao Xianjun ``` 64529690b6SJiao Xianjun Normally in the previous ssh session, the count becomes 1. It means one packet (of IQ sample) is sent and captured via loopback over the air. 65529690b6SJiao Xianjun 66c6dd9e71SJiao Xianjun If 1 is not seen, you can try to put the receiver into reset state, so it won't block the system in case it runs into dead state 67c6dd9e71SJiao Xianjun ``` 68c6dd9e71SJiao Xianjun ./sdrctl dev sdr0 set reg rx 0 1 69c6dd9e71SJiao Xianjun ``` 70c6dd9e71SJiao Xianjun 71529690b6SJiao Xianjun- On your computer (NOT ssh onboard!), run: 72529690b6SJiao Xianjun ``` 73529690b6SJiao Xianjun cd openwifi/user_space/side_ch_ctl_src 74529690b6SJiao Xianjun python3 iq_capture.py 8187 75529690b6SJiao Xianjun ``` 76529690b6SJiao Xianjun You might need to install beforehand: "sudo apt install python3-numpy", and "sudo apt install python3-matplotlib". 77529690b6SJiao Xianjun 78529690b6SJiao Xianjun- Leave the above host session untouched. Let's go to the second ssh session (packet injection), and do single packet Tx again: 79529690b6SJiao Xianjun ``` 80529690b6SJiao Xianjun ./inject_80211 -m n -r 5 -n 1 sdr0 81529690b6SJiao Xianjun ``` 82529690b6SJiao Xianjun Normally in the 1st ssh session, the count becomes 2. You should also see IQ sample capture figures like this: 83529690b6SJiao Xianjun  84529690b6SJiao Xianjun 85529690b6SJiao Xianjun- Stop the python3 script, which plots above, in the host session. A file **iq.txt** is generated. You can use the Matlab script test_iq_file_display.m 86529690b6SJiao Xianjunto do further offline analysis, or feed the IQ sample to the openwifi receiver simulation, etc. 87529690b6SJiao Xianjun 88529690b6SJiao Xianjun## Check the packet loopback on board 89529690b6SJiao Xianjun 90529690b6SJiao Xianjun- While signal/packet is looped back, you can capture it on board via normal sniffer program for further check/analysis on the packet (bit/byte level instead of IQ level), such as tcpdump or tshark. 91529690b6SJiao Xianjun A new ssh session to the board should be opened to do this before running the packet injection: 92529690b6SJiao Xianjun ``` 93529690b6SJiao Xianjun tcpdump -i sdr0 94529690b6SJiao Xianjun ``` 95c6dd9e71SJiao Xianjun Run the packet injection "./inject_80211 -m n -r 5 -n 1 sdr0" in another session, you should see the packet information printed by tcpdump from self over-the-air loopback. In case you put the receiver into reset state in the previous IQ loopback, you should put the receiver back to normal for packet loopback (otherwise the receiver won't decode the IQ signal back to packet): 96c6dd9e71SJiao Xianjun ``` 97c6dd9e71SJiao Xianjun ./sdrctl dev sdr0 set reg rx 0 0 98c6dd9e71SJiao Xianjun ``` 99529690b6SJiao Xianjun 100529690b6SJiao Xianjun- You can also see the openwifi printk message of Rx packet (self Tx looped back) while the packet comes to the openwifi Rx interrupt. 101529690b6SJiao Xianjun A new ssh session to the board should be opened to do this before running the packet injection: 102529690b6SJiao Xianjun ``` 103529690b6SJiao Xianjun cd openwifi 104529690b6SJiao Xianjun ./sdrctl dev sdr0 set reg drv_rx 7 7 105dbcf06d1SJiao Xianjun ./sdrctl dev sdr0 set reg drv_tx 7 7 106b6f91403Sredfast00 # Turn on the openwifi Tx/Rx printk logging 107529690b6SJiao Xianjun ``` 108dbcf06d1SJiao Xianjun Stop the "./side_ch_ctl g0" in the very first ssh session. Run the packet injection, then check the printk message: 109529690b6SJiao Xianjun ``` 110dbcf06d1SJiao Xianjun ./inject_80211/inject_80211 -m n -r 5 -n 1 sdr0 111529690b6SJiao Xianjun dmesg 112529690b6SJiao Xianjun ``` 113dbcf06d1SJiao Xianjun You should see the printk message of packet Tx and Rx from the openwifi driver (sdr.c). 114529690b6SJiao Xianjun 1157eea2988SXianjun Jiao## IQ self loopback config 116529690b6SJiao Xianjun 117529690b6SJiao Xianjun- By default, the loopback is via the air (from Tx antenna to Rx antenna). FPGA inernal loopback option is offered to have IQ sample and packet without 118dbcf06d1SJiao Xianjun any interference. To have FPGA internal loopback, replace the "./side_ch_ctl wh5h0" during setup (the very 1st ssh session) by: 119529690b6SJiao Xianjun ``` 120529690b6SJiao Xianjun ./side_ch_ctl wh5h4 121529690b6SJiao Xianjun ``` 122529690b6SJiao Xianjun- Lots of packet injection parameters can be set: number of packet, type (data/control/management), MCS/rate, size, interval, etc. Please run the packet injection 123529690b6SJiao Xianjun program without any arguments to see the help. 124529690b6SJiao Xianjun 125529690b6SJiao Xianjun- Besides the packet Tx via injection over monitor mode for loopback test, normal WiFi mode (AP/Client/ad-hoc) can also run together with self loopback. 126529690b6SJiao Xianjun For instance, run **fosdem.sh** instead of **wgd.sh** to setup an openwifi AP that will transmit beacons. The wgd.sh can also be replaced with other scenario 127529690b6SJiao Xianjun setup scripts. Please check [Application notes](README.md) 128529690b6SJiao Xianjun 129529690b6SJiao Xianjun- To understand deeper of all above commands/settings, please refer to [Capture IQ sample, AGC gain, RSSI with many types of trigger condition](iq.md) and 130529690b6SJiao Xianjun [Capture dual antenna TX/RX IQ for multi-purpose (capture collision)](iq_2ant.md) 1317eea2988SXianjun Jiao 1327eea2988SXianjun Jiao## CSI FPGA self loopback quick start 1337eea2988SXianjun Jiao 1347eea2988SXianjun JiaoThis section will show how to connect the WiFi OFDM transmitter to the receiver directly inside FPGA, and show the ideal CSI/constellation/frequency-offset. (For CSI over the air loopback, please refer to [CSI radar app note](radar-self-csi.md)) 1357eea2988SXianjun Jiao 1367eea2988SXianjun JiaoCommand sequence on board: 1377eea2988SXianjun Jiao``` 1387eea2988SXianjun Jiaocd openwifi 1397eea2988SXianjun Jiao./wgd.sh 1407eea2988SXianjun Jiao./monitor_ch.sh sdr0 6 1417eea2988SXianjun Jiaoinsmod side_ch.ko 1427eea2988SXianjun Jiao./side_ch_ctl g 1437eea2988SXianjun Jiao``` 1447eea2988SXianjun JiaoOpen another ssh session on board, then: 1457eea2988SXianjun Jiao``` 1467eea2988SXianjun Jiaocd openwifi 1477eea2988SXianjun Jiao./sdrctl dev sdr0 set reg rx_intf 3 256 1487eea2988SXianjun Jiao(Above command let the FPGA Tx IQ come to receiver directly. Set 256 back to 0 to let receiver back connect to AD9361 RF frontend) 149*ca63c39fSXianjun Jiao./sdrctl dev sdr0 set reg rx 5 768 150*ca63c39fSXianjun Jiao(Disable the receiver FFT window shift. By default it is 1 (768+1) -- good for multipath, overfitting for direct loopback) 1517eea2988SXianjun Jiao./inject_80211/inject_80211 -m n -r 7 -n 99999 -s 1400 -d 1000000 sdr0 1527eea2988SXianjun Jiao(Transmit 802.11n MCS7 1400Byte packet every second) 1537eea2988SXianjun Jiao``` 1547eea2988SXianjun Jiao 1557eea2988SXianjun JiaoCommand on computer: 1567eea2988SXianjun Jiao``` 1577eea2988SXianjun Jiaocd openwifi/user_space/side_ch_ctl_src 1587eea2988SXianjun Jiaopython3 side_info_display.py 1597eea2988SXianjun Jiao``` 1607eea2988SXianjun JiaoNow you should see the following screenshot that shows the CSI/constellation/frequency-offset over this in-FPGA ideal channel. 1617eea2988SXianjun Jiao 162