1*f71252c5SXianjun JiaoWe implement the **IQ sample capture** with interesting extensions: many **trigger conditions**; **RSSI**, RF chip **AGC** **status (lock/unlock)** and **gain**. 2*f71252c5SXianjun Jiao 3*f71252c5SXianjun Jiao## Quick start 4*f71252c5SXianjun Jiao- Power on the SDR board. 5*f71252c5SXianjun 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: 6*f71252c5SXianjun Jiao ``` 7*f71252c5SXianjun Jiao ssh [email protected] 8*f71252c5SXianjun Jiao (password: openwifi) 9*f71252c5SXianjun Jiao cd openwifi 10*f71252c5SXianjun Jiao ./wgd.sh 11*f71252c5SXianjun Jiao (Wait for the script completed) 12*f71252c5SXianjun Jiao ./monitor_ch.sh sdr0 11 13*f71252c5SXianjun Jiao (Monitor on channel 11. You can change 11 to other channel that is busy) 14*f71252c5SXianjun Jiao insmod side_ch.ko iq_len_init=8187 15*f71252c5SXianjun Jiao (for zed, adrv9364z7020, zc702 board, 8187 should be 4095 because they have smaller FPGA) 16*f71252c5SXianjun Jiao 17*f71252c5SXianjun Jiao ./side_ch_ctl wh11d4094 18*f71252c5SXianjun Jiao (Above command is needed only when you run with zed, adrv9364z7020, zc702 board) 19*f71252c5SXianjun Jiao 20*f71252c5SXianjun Jiao ./side_ch_ctl g 21*f71252c5SXianjun Jiao ``` 22*f71252c5SXianjun Jiao You should see on board outputs like: 23*f71252c5SXianjun Jiao ``` 24*f71252c5SXianjun Jiao loop 64 side info count 61 25*f71252c5SXianjun Jiao loop 128 side info count 99 26*f71252c5SXianjun Jiao ... 27*f71252c5SXianjun Jiao ``` 28*f71252c5SXianjun Jiao If the second number (61, 99, ...) is not zero and keeps increasing, that means the IQ sample is going to the computer smoothly. 29*f71252c5SXianjun Jiao 30*f71252c5SXianjun Jiao- Open another terminal on the computer, and run: 31*f71252c5SXianjun Jiao ``` 32*f71252c5SXianjun Jiao cd openwifi/user_space/side_ch_ctl_src 33*f71252c5SXianjun Jiao python3 iq_capture.py 34*f71252c5SXianjun Jiao (for zed, adrv9364z7020, zc702 board, add 4095 as parameter!) 35*f71252c5SXianjun Jiao ``` 36*f71252c5SXianjun 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**. 37*f71252c5SXianjun Jiao 38*f71252c5SXianjun Jiao While running, all informations are 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. 39*f71252c5SXianjun Jiao 40*f71252c5SXianjun Jiao## Understand the IQ capture feature 41*f71252c5SXianjun 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. 42*f71252c5SXianjun Jiao  43*f71252c5SXianjun Jiao 44*f71252c5SXianjun Jiao The IQ information format is shown in this figure. 45*f71252c5SXianjun Jiao  46*f71252c5SXianjun Jiao 47*f71252c5SXianjun Jiao For each element, the actual size is 64bit. 48*f71252c5SXianjun Jiao - timestamp: 64bit TSF timer value when the capture is triggered. 49*f71252c5SXianjun Jiao - IQ 50*f71252c5SXianjun Jiao - The first two 16bit are used for I/Q sample 51*f71252c5SXianjun Jiao - The 3rd 16bit is AD9361 AGC gain (bit7 -- lock/unlock; bit6~0 -- gain value) 52*f71252c5SXianjun 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. 53*f71252c5SXianjun Jiao 54*f71252c5SXianjun Jiao The python and Matlab scripts are recommended for you to understand the IQ packet format precisely. 55*f71252c5SXianjun Jiao 56*f71252c5SXianjun Jiao## Config the IQ capture and interval 57*f71252c5SXianjun Jiao The quick start guide capture 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 condition and length, configuration command 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. 58*f71252c5SXianjun Jiao  59*f71252c5SXianjun Jiao 60*f71252c5SXianjun 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. 61*f71252c5SXianjun Jiao - pre_trigger_len 62*f71252c5SXianjun Jiao ``` 63*f71252c5SXianjun Jiao ./side_ch_ctl wh11dY 64*f71252c5SXianjun Jiao ``` 65*f71252c5SXianjun Jiao 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), valid range is 0 ~ **4094**. 66*f71252c5SXianjun Jiao - trigger condition 67*f71252c5SXianjun Jiao ``` 68*f71252c5SXianjun Jiao ./side_ch_ctl wh8dY 69*f71252c5SXianjun Jiao ``` 70*f71252c5SXianjun Jiao The parameter **Y** specifies the trigger condition. Valid range 0 ~ 15, which is explained in this table. 71*f71252c5SXianjun Jiao 72*f71252c5SXianjun Jiao value|meaning 73*f71252c5SXianjun Jiao -----|------- 74*f71252c5SXianjun Jiao 0 |receiver gives FCS checksum result. no matter pass/fail 75*f71252c5SXianjun Jiao 1 |receiver gives FCS checksum result. pass 76*f71252c5SXianjun Jiao 2 |receiver gives FCS checksum result. fail 77*f71252c5SXianjun Jiao 3 |receiver gives SIGNAL field checksum result. no matter pass/fail 78*f71252c5SXianjun Jiao 4 |receiver gives SIGNAL field checksum result. pass 79*f71252c5SXianjun Jiao 5 |receiver gives SIGNAL field checksum result. fail 80*f71252c5SXianjun Jiao 6 |receiver gives SIGNAL field checksum result. no matter pass/fail. HT packet 81*f71252c5SXianjun Jiao 7 |receiver gives SIGNAL field checksum result. no matter pass/fail. non-HT packet 82*f71252c5SXianjun Jiao 8 |receiver gives long preamble detected 83*f71252c5SXianjun Jiao 9 |receiver gives short preamble detected 84*f71252c5SXianjun Jiao 10|RSSI (half dB uncalibrated) goes above the threshold 85*f71252c5SXianjun Jiao 11|RSSI (half dB uncalibrated) goes below the threshold 86*f71252c5SXianjun Jiao 12|AD9361 AGC from lock to unlock 87*f71252c5SXianjun Jiao 13|AD9361 AGC from unlock to lock 88*f71252c5SXianjun Jiao 14|AD9361 AGC gain goes above the threshold 89*f71252c5SXianjun Jiao 15|AD9361 AGC gain goes below the threshold 90*f71252c5SXianjun Jiao 91*f71252c5SXianjun Jiao To set the RSSI threshold 92*f71252c5SXianjun Jiao ``` 93*f71252c5SXianjun Jiao ./side_ch_ctl wh9dY 94*f71252c5SXianjun Jiao ``` 95*f71252c5SXianjun Jiao The parameter **Y** specifies the RSSI threshold. Valid range 0 ~ 2047. 96*f71252c5SXianjun Jiao 97*f71252c5SXianjun Jiao To set the AGC gain threshold 98*f71252c5SXianjun Jiao ``` 99*f71252c5SXianjun Jiao ./side_ch_ctl wh10dY 100*f71252c5SXianjun Jiao ``` 101*f71252c5SXianjun Jiao The parameter **Y** specifies the AGC gain threshold. Valid range 0 ~ 127. 102*f71252c5SXianjun Jiao 103*f71252c5SXianjun Jiao The command "**side_ch_ctl g**" will perform IQ capture every 100ms until you press ctrl+C. To use a different capture interval: 104*f71252c5SXianjun Jiao ``` 105*f71252c5SXianjun Jiao side_ch_ctl gN 106*f71252c5SXianjun Jiao ``` 107*f71252c5SXianjun Jiao The interval will become N*1ms 108*f71252c5SXianjun Jiao 109*f71252c5SXianjun Jiao## Config the iq_len 110*f71252c5SXianjun Jiao 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), valid range is 0 ~ **4095**. It is independant form 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. 111*f71252c5SXianjun Jiao - When insert the kernel module, use: 112*f71252c5SXianjun Jiao ``` 113*f71252c5SXianjun Jiao insmod side_ch.ko iq_len_init=3000 114*f71252c5SXianjun Jiao ``` 115*f71252c5SXianjun Jiao Here 3000 is an example. **ATTENTION:** You need to specify **iq_len_init** explicitly to turn on IQ capture, which will turn off CSI. Insert the side_ch.ko without any parameter will run CSI mode. 116*f71252c5SXianjun Jiao - When launch the python script, use: 117*f71252c5SXianjun Jiao ``` 118*f71252c5SXianjun Jiao python3 iq_capture.py 3000 119*f71252c5SXianjun Jiao ``` 120*f71252c5SXianjun Jiao - When use the matlab script, please change the **iq_len** variable in the script to 3000. 121*f71252c5SXianjun Jiao 122*f71252c5SXianjun Jiao## Compile the side channel driver and user space program 123*f71252c5SXianjun Jiao - side_ch.ko 124*f71252c5SXianjun Jiao ``` 125*f71252c5SXianjun Jiao $OPENWIFI_DIR/driver/side_ch/make_driver.sh $OPENWIFI_DIR $XILINX_DIR ARCH_BIT 126*f71252c5SXianjun Jiao(For Zynq 7000, ARCH_BIT should be 32, for Zynq MPSoC, ARCH_BIT should be 64) 127*f71252c5SXianjun Jiao ``` 128*f71252c5SXianjun Jiao - side_ch_ctl (take user_space/side_ch_ctl_src/side_ch_ctl.c and compile it on board!) 129*f71252c5SXianjun Jiao ``` 130*f71252c5SXianjun Jiao gcc -o side_ch_ctl side_ch_ctl.c 131*f71252c5SXianjun Jiao ``` 132*f71252c5SXianjun Jiao 133*f71252c5SXianjun Jiao## Run the IQ capture together with modes other than monitor 134*f71252c5SXianjun 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. 135*f71252c5SXianjun Jiao 136*f71252c5SXianjun Jiao## Map the IQ information to the WiFi packet 137*f71252c5SXianjun 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. 138*f71252c5SXianjun Jiao 139*f71252c5SXianjun Jiao Please learn the python and Matlab script to extract IQ information per capture according to your requirement. 140