1a6085186SLina Ceballos<!-- 2c2a4db0eSJiao XianjunAuthor: Xianjun jiao 3c2a4db0eSJiao XianjunSPDX-FileCopyrightText: 2019 UGent 4a6085186SLina CeballosSPDX-License-Identifier: AGPL-3.0-or-later 5a6085186SLina Ceballos--> 6a6085186SLina Ceballos 7a6085186SLina Ceballos 8f71252c5SXianjun JiaoWe implement the **IQ sample capture** with interesting extensions: many **trigger conditions**; **RSSI**, RF chip **AGC** **status (lock/unlock)** and **gain**. 9f71252c5SXianjun Jiao 1057b28bf2SJiao Xianjun(By default, openwifi Rx baseband is muted during self Tx, to unmute Rx baseband and capture self Tx signal you need to run "./sdrctl dev sdr0 set reg xpu 1 1" after the test running) 1157b28bf2SJiao Xianjun 12f71252c5SXianjun Jiao## Quick start 13f71252c5SXianjun Jiao- Power on the SDR board. 14f71252c5SXianjun Jiao- 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: 15f71252c5SXianjun Jiao ``` 16f71252c5SXianjun Jiao ssh [email protected] 17f71252c5SXianjun Jiao (password: openwifi) 18f71252c5SXianjun Jiao cd openwifi 19f71252c5SXianjun Jiao ./wgd.sh 20f71252c5SXianjun Jiao (Wait for the script completed) 21f71252c5SXianjun Jiao ./monitor_ch.sh sdr0 11 22f71252c5SXianjun Jiao (Monitor on channel 11. You can change 11 to other channel that is busy) 23f71252c5SXianjun Jiao insmod side_ch.ko iq_len_init=8187 2401754872SXianjun Jiao (for smaller FPGA (7Z020), iq_len_init should be <4096, like 4095, instead of 8187) 25f71252c5SXianjun Jiao 26f71252c5SXianjun Jiao ./side_ch_ctl wh11d4094 27f71252c5SXianjun Jiao (Above command is needed only when you run with zed, adrv9364z7020, zc702 board) 28f71252c5SXianjun Jiao 29f71252c5SXianjun Jiao ./side_ch_ctl g 30f71252c5SXianjun Jiao ``` 31f71252c5SXianjun Jiao You should see on board outputs like: 32f71252c5SXianjun Jiao ``` 33f71252c5SXianjun Jiao loop 64 side info count 61 34f71252c5SXianjun Jiao loop 128 side info count 99 35f71252c5SXianjun Jiao ... 36f71252c5SXianjun Jiao ``` 375deb8d18SXianjun Jiao If the second number (side info count 61, 99, ...) keeps increasing, that means the trigger condition is met from time to time and the IQ sample is going to the computer smoothly. 38f71252c5SXianjun Jiao 39f71252c5SXianjun Jiao- Open another terminal on the computer, and run: 40f71252c5SXianjun Jiao ``` 41f71252c5SXianjun Jiao cd openwifi/user_space/side_ch_ctl_src 42f71252c5SXianjun Jiao python3 iq_capture.py 4301754872SXianjun Jiao (for zed, adrv9364z7020, zc702 board, add argument that euqals to iq_len_init, like 4095) 44f71252c5SXianjun Jiao ``` 45f71252c5SXianjun Jiao The python script needs "matplotlib.pyplot" and "numpy" packages installed. Now you should see 3 figures showing run-time **IQ sample**, **AGC gain and lock status** and **RSSI (uncalibrated)**. Meanwhile the python script prints the **timestamp**. 46fbadfe45SJiao Xianjun  47f71252c5SXianjun Jiao 48b1dd94e3Sluz paz While running, all information is also stored into a file **iq.txt**. A matlab script **test_iq_file_display.m** is offered to help you do analysis on the IQ Information offline. For zed, adrv9364z7020, zc702 board, do not forget to change the **iq_len** in the matlab script to 4095. 49f71252c5SXianjun Jiao 50f71252c5SXianjun Jiao## Understand the IQ capture feature 51f71252c5SXianjun Jiao The IQ information is extracted via the openwifi **side channel** infrastructure. This figure explains the related modules (also related source code file name) and how the information goes from the SDR board to the computer. 52f71252c5SXianjun Jiao  53f71252c5SXianjun Jiao 54f71252c5SXianjun Jiao The IQ information format is shown in this figure. 55f71252c5SXianjun Jiao  56f71252c5SXianjun Jiao 57f71252c5SXianjun Jiao For each element, the actual size is 64bit. 58f71252c5SXianjun Jiao - timestamp: 64bit TSF timer value when the capture is triggered. 59f71252c5SXianjun Jiao - IQ 605deb8d18SXianjun Jiao - The first two 16bit are used for I/Q sample from the antenna currently used 61f71252c5SXianjun Jiao - The 3rd 16bit is AD9361 AGC gain (bit7 -- lock/unlock; bit6~0 -- gain value) 62f71252c5SXianjun Jiao - The 4th 16bit is RSSI (half dB, uncalibrated). Please check xpu.v and sdr.c to understand how the raw RSSI value is finally calibrated and reported to Linux mac80211. 63f71252c5SXianjun Jiao 64f71252c5SXianjun Jiao The python and Matlab scripts are recommended for you to understand the IQ packet format precisely. 65f71252c5SXianjun Jiao 66f71252c5SXianjun Jiao## Config the IQ capture and interval 679ab264e2SJiao Xianjun The quick start guide captures a period of history IQ when the packet FCS checksum is checked by Wifi receiver (no matter pass or fail). To initiate the capture with different trigger conditions and length, configuration commands should be issued before executing "**side_ch_ctl g**". The configuration command is realized by feeding a different parameter to "**side_ch_ctl**". The main parameters that are configurable are explained in this figure. 68f71252c5SXianjun Jiao  69f71252c5SXianjun Jiao 70f71252c5SXianjun Jiao **iq_len** is the number of IQ samples captured per trigger condition met. The capture is started from the time **pre_trigger_len** IQ samples before the trigger moment. **iq_len** is set only one time when you insert the side_ch.ko. Please check the next section for **iq_len** configuration. This section introduces the setting of pre_trigger_len and trigger condition. 71f71252c5SXianjun Jiao - pre_trigger_len 72f71252c5SXianjun Jiao ``` 73f71252c5SXianjun Jiao ./side_ch_ctl wh11dY 74f71252c5SXianjun Jiao ``` 759ab264e2SJiao Xianjun The parameter **Y** specifies the pre_trigger_len. Valid range 0 ~ 8190. It is limited by the FPGA fifo size. For **small FPGA** (zed_fmcs2, adrv9364z7020, zc702), the valid range is 0 ~ **4094**. 76f71252c5SXianjun Jiao - trigger condition 77f71252c5SXianjun Jiao ``` 78f71252c5SXianjun Jiao ./side_ch_ctl wh8dY 79f71252c5SXianjun Jiao ``` 805deb8d18SXianjun Jiao The parameter **Y** specifies the trigger condition. Valid range 0 ~ 31, which is explained in this table. 81f71252c5SXianjun Jiao 82f71252c5SXianjun Jiao value|meaning 83f71252c5SXianjun Jiao -----|------- 84f71252c5SXianjun Jiao 0 |receiver gives FCS checksum result. no matter pass/fail 85f71252c5SXianjun Jiao 1 |receiver gives FCS checksum result. pass 86f71252c5SXianjun Jiao 2 |receiver gives FCS checksum result. fail 871f03c61aSXianjun Jiao 3 |the tx_intf_iq0 becomes non zero (the 1st I/Q out) 88f71252c5SXianjun Jiao 4 |receiver gives SIGNAL field checksum result. pass 89f71252c5SXianjun Jiao 5 |receiver gives SIGNAL field checksum result. fail 90f71252c5SXianjun Jiao 6 |receiver gives SIGNAL field checksum result. no matter pass/fail. HT packet 91f71252c5SXianjun Jiao 7 |receiver gives SIGNAL field checksum result. no matter pass/fail. non-HT packet 92f71252c5SXianjun Jiao 8 |receiver gives long preamble detected 93f71252c5SXianjun Jiao 9 |receiver gives short preamble detected 94f71252c5SXianjun Jiao 10|RSSI (half dB uncalibrated) goes above the threshold 95f71252c5SXianjun Jiao 11|RSSI (half dB uncalibrated) goes below the threshold 96f71252c5SXianjun Jiao 12|AD9361 AGC from lock to unlock 97f71252c5SXianjun Jiao 13|AD9361 AGC from unlock to lock 98f71252c5SXianjun Jiao 14|AD9361 AGC gain goes above the threshold 99f71252c5SXianjun Jiao 15|AD9361 AGC gain goes below the threshold 1005deb8d18SXianjun Jiao 16|phy_tx_started signal from openofdm tx core 1015deb8d18SXianjun Jiao 17|phy_tx_done signal from openofdm tx core 1025deb8d18SXianjun Jiao 18|positive edge of tx_bb_is_ongoing from xpu core 1035deb8d18SXianjun Jiao 19|negative edge of tx_bb_is_ongoing from xpu core 1045deb8d18SXianjun Jiao 20|positive edge of tx_rf_is_ongoing from xpu core 1055deb8d18SXianjun Jiao 21|negative edge of tx_rf_is_ongoing from xpu core 1065deb8d18SXianjun Jiao 22|phy_tx_started and this tx packet needs ACK 1075deb8d18SXianjun Jiao 23|phy_tx_done and this tx packet needs ACK 1085deb8d18SXianjun Jiao 24|positive edge of tx_bb_is_ongoing and this tx packet needs ACK 1095deb8d18SXianjun Jiao 25|negative edge of tx_bb_is_ongoing and this tx packet needs ACK 1105deb8d18SXianjun Jiao 26|positive edge of tx_rf_is_ongoing and this tx packet needs ACK 1115deb8d18SXianjun Jiao 27|negative edge of tx_rf_is_ongoing and this tx packet needs ACK 1125deb8d18SXianjun Jiao 28|tx_bb_is_ongoing and I/Q amplitude from the other antenna is above rssi_or_iq_th 1135deb8d18SXianjun Jiao 29|tx_rf_is_ongoing and I/Q amplitude from the other antenna is above rssi_or_iq_th 114941d19cfSJiao Xianjun 30|start tx, meanwhile I/Q amplitude from the other antenna is above rssi_or_iq_th 115941d19cfSJiao Xianjun 31|start tx and need for ACK, meanwhile I/Q amplitude from the other antenna is above rssi_or_iq_th 116f71252c5SXianjun Jiao 11723ba65e4SXianjun Jiao If free running is wanted (alway trigger), please use the following two commands together. 11823ba65e4SXianjun Jiao ``` 11923ba65e4SXianjun Jiao ./side_ch_ctl wh8d0 12023ba65e4SXianjun Jiao ./side_ch_ctl wh5d1 12123ba65e4SXianjun Jiao ``` 12223ba65e4SXianjun Jiao 123f71252c5SXianjun Jiao To set the RSSI threshold 124f71252c5SXianjun Jiao ``` 125f71252c5SXianjun Jiao ./side_ch_ctl wh9dY 126f71252c5SXianjun Jiao ``` 127f71252c5SXianjun Jiao The parameter **Y** specifies the RSSI threshold. Valid range 0 ~ 2047. 128f71252c5SXianjun Jiao 129f71252c5SXianjun Jiao To set the AGC gain threshold 130f71252c5SXianjun Jiao ``` 131f71252c5SXianjun Jiao ./side_ch_ctl wh10dY 132f71252c5SXianjun Jiao ``` 133f71252c5SXianjun Jiao The parameter **Y** specifies the AGC gain threshold. Valid range 0 ~ 127. 134f71252c5SXianjun Jiao 135f71252c5SXianjun Jiao The command "**side_ch_ctl g**" will perform IQ capture every 100ms until you press ctrl+C. To use a different capture interval: 136f71252c5SXianjun Jiao ``` 137f71252c5SXianjun Jiao side_ch_ctl gN 138f71252c5SXianjun Jiao ``` 139f71252c5SXianjun Jiao The interval will become N*1ms 140f71252c5SXianjun Jiao 141f71252c5SXianjun Jiao## Config the iq_len 142b1dd94e3Sluz paz The **iq_len** (number of IQ sample per capture) is configurable in case you want less IQ samples per capture so that it can be triggered more times during a specific analysis period. The valid value is 1~**8187**. For **small FPGA** (zed_fmcs2, adrv9364z7020, zc702), the valid range is 0 ~ **4095**. It is independent from pre_trigger_len, and it can be less than pre_trigger_len if you want. You should align the **iq_len** value at the side_ch.ko, iq_capture.py and test_iq_file_display.m. 143f71252c5SXianjun Jiao - When insert the kernel module, use: 144f71252c5SXianjun Jiao ``` 145f71252c5SXianjun Jiao insmod side_ch.ko iq_len_init=3000 146f71252c5SXianjun Jiao ``` 1475deb8d18SXianjun Jiao Here 3000 is an example. **ATTENTION:** You need to specify **iq_len_init** explicitly to turn on IQ capture, which will turn off the default CSI mode. Insert the side_ch.ko without any parameter will run the default CSI mode. 148f71252c5SXianjun Jiao - When launch the python script, use: 149f71252c5SXianjun Jiao ``` 150f71252c5SXianjun Jiao python3 iq_capture.py 3000 151f71252c5SXianjun Jiao ``` 152f71252c5SXianjun Jiao - When use the matlab script, please change the **iq_len** variable in the script to 3000. 153f71252c5SXianjun Jiao 154f71252c5SXianjun Jiao## Compile the side channel driver and user space program 155f71252c5SXianjun Jiao - side_ch.ko 156f71252c5SXianjun Jiao ``` 157f71252c5SXianjun Jiao $OPENWIFI_DIR/driver/side_ch/make_driver.sh $OPENWIFI_DIR $XILINX_DIR ARCH_BIT 158f71252c5SXianjun Jiao(For Zynq 7000, ARCH_BIT should be 32, for Zynq MPSoC, ARCH_BIT should be 64) 159f71252c5SXianjun Jiao ``` 160f71252c5SXianjun Jiao - side_ch_ctl (take user_space/side_ch_ctl_src/side_ch_ctl.c and compile it on board!) 161f71252c5SXianjun Jiao ``` 162f71252c5SXianjun Jiao gcc -o side_ch_ctl side_ch_ctl.c 163f71252c5SXianjun Jiao ``` 164f71252c5SXianjun Jiao 165f71252c5SXianjun Jiao## Run the IQ capture together with modes other than monitor 166f71252c5SXianjun Jiao The openwifi IQ capture feature could run with not only monitor mode but also other modes, such as AP-Client or ad-hoc mode. After the communication functionality is fully up in those modes, you can start IQ capture from "**insmod side_ch.ko**" and "**./side_ch_ctl g**" on board as described in the previous sections to extract IQ information to your computer. 167f71252c5SXianjun Jiao 168f71252c5SXianjun Jiao## Map the IQ information to the WiFi packet 169*d79dd9b7SJiao Xianjun (See this https://github.com/open-sdr/openwifi/discussions/344 to understand how to map the collected data to the packet via the TSF timestamp) 170*d79dd9b7SJiao Xianjun 171f71252c5SXianjun Jiao If you want to relate the IQ information to the WiFi packet, you need to capture WiFi packets (tcpdump/wireshark/etc) while capturing IQ. Then you can relate the timestamp between WiFi packet and IQ information. Please be noticed that the timestamp in the IQ information is the moment when capture is triggered, which could be different from the timestamp reported in the packet capture program. But since they share the same time base (TSF timer), you can relate them easily by analyzing the WiFi packet and IQ sample sequence. 172f71252c5SXianjun Jiao 173f71252c5SXianjun Jiao Please learn the python and Matlab script to extract IQ information per capture according to your requirement. 174