xref: /openwifi/doc/app_notes/packet-iq-self-loopback-test.md (revision fc4a13a9ca2630c623cc500e80f7ed6800bb5eb9)
1<!--
2Author: Xianjun Jiao
3SPDX-FileCopyrightText: 2022 UGent
4SPDX-License-Identifier: AGPL-3.0-or-later
5-->
6
7One super power of the openwifi platform is "**Full Duplex**" which means that openwifi baseband can receive its own TX signal.
8This 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.
9![](./openwifi-loopback-principle.jpg)
10
11[[IQ self loopback quick start](#IQ-self-loopback-quick-start)]
12[[Check the packet loopback on board](#Check-the-packet-loopback-on-board)]
13[[IQ self loopback config](#IQ-self-loopback-config)]
14[[CSI FPGA self loopback quick start](#CSI-FPGA-self-loopback-quick-start)]
15
16## IQ self loopback quick start
17(Please replace the IQ length **8187** by **4095** if you use low end FPGA board: zedboard/adrv9464z7020/antsdr/zc702/sdrpi)
18- Power on the SDR board.
19- Put the Tx and Rx antenna as close as possible.
20- 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:
21  ```
22  # ssh into the SDR board, password: openwifi
23  ssh [email protected]
24  cd openwifi
25  # Bring up the openwifi NIC sdr0
26  ./wgd.sh
27
28  # 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.
29  ./monitor_ch.sh sdr0 44
30
31  # 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)
32  ./sdrctl dev sdr0 set reg xpu 8 1000
33
34  # Load side channel kernel module with buffer lenght of 8187 (replace this with 4095 when using low end FPGA board)
35  insmod side_ch.ko iq_len_init=8187
36
37  # Set 100 to register 11. It means the pre trigger length is 100, so we mainly capture IQ after trigger condition is met
38  ./side_ch_ctl wh11d100
39  # Set 16 to register 8 -- set trigger condition to phy_tx_started signal from openofdm tx core
40  ./side_ch_ctl wh8d16
41  # Unmute the baseband self-receiving to receive openwifi own TX signal/packet -- important for self loopback!
42  ./sdrctl dev sdr0 set reg xpu 1 1
43  # Set the loopback mode to over-the-air
44  ./side_ch_ctl wh5h0
45  # Relay the FPGA IQ capture to the host computer that will show the captured IQ later on)
46  ./side_ch_ctl g0
47  ```
48  You should see on outputs like:
49  ```
50  loop 22848 side info count 0
51  loop 22912 side info count 0
52  ...
53  ```
54  Now the count is always 0, because we haven't instructed openwifi to send packet for loopback test.
55
56- Leave above ssh session untouched. Open a new ssh session to the board from your computer. Then run on board:
57  ```
58  cd openwifi/inject_80211/
59  make
60  # Build our example packet injection program
61  ./inject_80211 -m n -r 5 -n 1 sdr0
62  # Inject one packet to openwifi sdr0 NIC
63  ```
64  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.
65
66  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
67  ```
68  ./sdrctl dev sdr0 set reg rx 0 1
69  ```
70
71- On your computer (NOT ssh onboard!), run:
72  ```
73  cd openwifi/user_space/side_ch_ctl_src
74  python3 iq_capture.py 8187
75  ```
76  You might need to install beforehand: "sudo apt install python3-numpy", and "sudo apt install python3-matplotlib".
77
78- Leave the above host session untouched. Let's go to the second ssh session (packet injection), and do single packet Tx again:
79  ```
80  ./inject_80211 -m n -r 5 -n 1 sdr0
81  ```
82  Normally in the 1st ssh session, the count becomes 2. You should also see IQ sample capture figures like this:
83  ![](./openwifi-iq-loopback.jpg)
84
85- 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
86to do further offline analysis, or feed the IQ sample to the openwifi receiver simulation, etc.
87
88## Check the packet loopback on board
89
90- 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.
91  A new ssh session to the board should be opened to do this before running the packet injection:
92  ```
93  tcpdump -i sdr0
94  ```
95  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):
96  ```
97  ./sdrctl dev sdr0 set reg rx 0 0
98  ```
99
100- You can also see the openwifi printk message of Rx packet (self Tx looped back) while the packet comes to the openwifi Rx interrupt.
101  A new ssh session to the board should be opened to do this before running the packet injection:
102  ```
103  cd openwifi
104  ./sdrctl dev sdr0 set reg drv_rx 7 7
105  ./sdrctl dev sdr0 set reg drv_tx 7 7
106  # Turn on the openwifi Tx/Rx printk logging
107  ```
108  Stop the "./side_ch_ctl g0" in the very first ssh session. Run the packet injection, then check the printk message:
109  ```
110  ./inject_80211/inject_80211 -m n -r 5 -n 1 sdr0
111  dmesg
112  ```
113  You should see the printk message of packet Tx and Rx from the openwifi driver (sdr.c).
114
115## IQ self loopback config
116
117- 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
118  any interference. To have FPGA internal loopback, replace the "./side_ch_ctl wh5h0" during setup (the very 1st ssh session) by:
119  ```
120  ./side_ch_ctl wh5h4
121  ```
122- 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
123  program without any arguments to see the help.
124
125- 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.
126  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
127  setup scripts. Please check [Application notes](README.md)
128
129- 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
130  [Capture dual antenna TX/RX IQ for multi-purpose (capture collision)](iq_2ant.md)
131
132## CSI FPGA self loopback quick start
133
134This 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))
135
136Command sequence on board:
137```
138cd openwifi
139./wgd.sh
140./monitor_ch.sh sdr0 6
141insmod side_ch.ko
142./side_ch_ctl g
143```
144Open another ssh session on board, then:
145```
146cd openwifi
147./sdrctl dev sdr0 set reg rx_intf 3 256
148(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./sdrctl dev sdr0 set reg rx 5 768
150(Disable the receiver FFT window shift. By default it is 1 (768+1) -- good for multipath, overfitting for direct loopback)
151./inject_80211/inject_80211 -m n -r 7 -n 99999 -s 1400 -d 1000000 sdr0
152(Transmit 802.11n MCS7 1400Byte packet every second)
153```
154
155Command on computer:
156```
157cd openwifi/user_space/side_ch_ctl_src
158python3 side_info_display.py
159```
160Now you should see the following screenshot that shows the CSI/constellation/frequency-offset over this in-FPGA ideal channel.
161![](./openwifi-csi-fpga-loopback.jpg)
162