xref: /openwifi/doc/app_notes/iq.md (revision fbadfe45ef6bb938fe684462c94b2da8040d3e74)
1f71252c5SXianjun JiaoWe implement the **IQ sample capture** with interesting extensions: many **trigger conditions**; **RSSI**, RF chip **AGC** **status (lock/unlock)** and **gain**.
2f71252c5SXianjun Jiao
3f71252c5SXianjun Jiao## Quick start
4f71252c5SXianjun Jiao- Power on the SDR board.
5f71252c5SXianjun 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:
6f71252c5SXianjun Jiao  ```
7f71252c5SXianjun Jiao  ssh [email protected]
8f71252c5SXianjun Jiao  (password: openwifi)
9f71252c5SXianjun Jiao  cd openwifi
10f71252c5SXianjun Jiao  ./wgd.sh
11f71252c5SXianjun Jiao  (Wait for the script completed)
12f71252c5SXianjun Jiao  ./monitor_ch.sh sdr0 11
13f71252c5SXianjun Jiao  (Monitor on channel 11. You can change 11 to other channel that is busy)
14f71252c5SXianjun Jiao  insmod side_ch.ko iq_len_init=8187
1501754872SXianjun Jiao  (for smaller FPGA (7Z020), iq_len_init should be <4096, like 4095, instead of 8187)
16f71252c5SXianjun Jiao
17f71252c5SXianjun Jiao  ./side_ch_ctl wh11d4094
18f71252c5SXianjun Jiao  (Above command is needed only when you run with zed, adrv9364z7020, zc702 board)
19f71252c5SXianjun Jiao
20f71252c5SXianjun Jiao  ./side_ch_ctl g
21f71252c5SXianjun Jiao  ```
22f71252c5SXianjun Jiao  You should see on board outputs like:
23f71252c5SXianjun Jiao  ```
24f71252c5SXianjun Jiao  loop 64 side info count 61
25f71252c5SXianjun Jiao  loop 128 side info count 99
26f71252c5SXianjun Jiao  ...
27f71252c5SXianjun Jiao  ```
285deb8d18SXianjun 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.
29f71252c5SXianjun Jiao
30f71252c5SXianjun Jiao- Open another terminal on the computer, and run:
31f71252c5SXianjun Jiao  ```
32f71252c5SXianjun Jiao  cd openwifi/user_space/side_ch_ctl_src
33f71252c5SXianjun Jiao  python3 iq_capture.py
3401754872SXianjun Jiao  (for zed, adrv9364z7020, zc702 board, add argument that euqals to iq_len_init, like 4095)
35f71252c5SXianjun Jiao  ```
36f71252c5SXianjun 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*fbadfe45SJiao Xianjun  ![](./iq-screen-shot.jpg)
38f71252c5SXianjun Jiao
39f71252c5SXianjun 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.
40f71252c5SXianjun Jiao
41f71252c5SXianjun Jiao## Understand the IQ capture feature
42f71252c5SXianjun 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.
43f71252c5SXianjun Jiao  ![](./iq-architecture.jpg)
44f71252c5SXianjun Jiao
45f71252c5SXianjun Jiao  The IQ information format is shown in this figure.
46f71252c5SXianjun Jiao  ![](./iq-information-format.jpg)
47f71252c5SXianjun Jiao
48f71252c5SXianjun Jiao  For each element, the actual size is 64bit.
49f71252c5SXianjun Jiao  - timestamp: 64bit TSF timer value when the capture is triggered.
50f71252c5SXianjun Jiao  - IQ
515deb8d18SXianjun Jiao    - The first two 16bit are used for I/Q sample from the antenna currently used
52f71252c5SXianjun Jiao    - The 3rd 16bit is AD9361 AGC gain (bit7 -- lock/unlock; bit6~0 -- gain value)
53f71252c5SXianjun 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.
54f71252c5SXianjun Jiao
55f71252c5SXianjun Jiao  The python and Matlab scripts are recommended for you to understand the IQ packet format precisely.
56f71252c5SXianjun Jiao
57f71252c5SXianjun Jiao## Config the IQ capture and interval
589ab264e2SJiao 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.
59f71252c5SXianjun Jiao  ![](./iq-capture-parameter.jpg)
60f71252c5SXianjun Jiao
61f71252c5SXianjun 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.
62f71252c5SXianjun Jiao  - pre_trigger_len
63f71252c5SXianjun Jiao  ```
64f71252c5SXianjun Jiao  ./side_ch_ctl wh11dY
65f71252c5SXianjun Jiao  ```
669ab264e2SJiao 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**.
67f71252c5SXianjun Jiao  - trigger condition
68f71252c5SXianjun Jiao  ```
69f71252c5SXianjun Jiao  ./side_ch_ctl wh8dY
70f71252c5SXianjun Jiao  ```
715deb8d18SXianjun Jiao  The parameter **Y** specifies the trigger condition. Valid range 0 ~ 31, which is explained in this table.
72f71252c5SXianjun Jiao
73f71252c5SXianjun Jiao  value|meaning
74f71252c5SXianjun Jiao  -----|-------
75f71252c5SXianjun Jiao  0 |receiver gives FCS checksum result. no matter pass/fail
76f71252c5SXianjun Jiao  1 |receiver gives FCS checksum result. pass
77f71252c5SXianjun Jiao  2 |receiver gives FCS checksum result. fail
78f71252c5SXianjun Jiao  3 |receiver gives SIGNAL field checksum result. no matter pass/fail
79f71252c5SXianjun Jiao  4 |receiver gives SIGNAL field checksum result. pass
80f71252c5SXianjun Jiao  5 |receiver gives SIGNAL field checksum result. fail
81f71252c5SXianjun Jiao  6 |receiver gives SIGNAL field checksum result. no matter pass/fail. HT packet
82f71252c5SXianjun Jiao  7 |receiver gives SIGNAL field checksum result. no matter pass/fail. non-HT packet
83f71252c5SXianjun Jiao  8 |receiver gives  long preamble detected
84f71252c5SXianjun Jiao  9 |receiver gives short preamble detected
85f71252c5SXianjun Jiao  10|RSSI (half dB uncalibrated) goes above the threshold
86f71252c5SXianjun Jiao  11|RSSI (half dB uncalibrated) goes below the threshold
87f71252c5SXianjun Jiao  12|AD9361 AGC from lock to unlock
88f71252c5SXianjun Jiao  13|AD9361 AGC from unlock to lock
89f71252c5SXianjun Jiao  14|AD9361 AGC gain goes above the threshold
90f71252c5SXianjun Jiao  15|AD9361 AGC gain goes below the threshold
915deb8d18SXianjun Jiao  16|phy_tx_started signal from openofdm tx core
925deb8d18SXianjun Jiao  17|phy_tx_done signal from openofdm tx core
935deb8d18SXianjun Jiao  18|positive edge of tx_bb_is_ongoing from xpu core
945deb8d18SXianjun Jiao  19|negative edge of tx_bb_is_ongoing from xpu core
955deb8d18SXianjun Jiao  20|positive edge of tx_rf_is_ongoing from xpu core
965deb8d18SXianjun Jiao  21|negative edge of tx_rf_is_ongoing from xpu core
975deb8d18SXianjun Jiao  22|phy_tx_started and this tx packet needs ACK
985deb8d18SXianjun Jiao  23|phy_tx_done and this tx packet needs ACK
995deb8d18SXianjun Jiao  24|positive edge of tx_bb_is_ongoing and this tx packet needs ACK
1005deb8d18SXianjun Jiao  25|negative edge of tx_bb_is_ongoing and this tx packet needs ACK
1015deb8d18SXianjun Jiao  26|positive edge of tx_rf_is_ongoing and this tx packet needs ACK
1025deb8d18SXianjun Jiao  27|negative edge of tx_rf_is_ongoing and this tx packet needs ACK
1035deb8d18SXianjun Jiao  28|tx_bb_is_ongoing and I/Q amplitude from the other antenna is above rssi_or_iq_th
1045deb8d18SXianjun Jiao  29|tx_rf_is_ongoing and I/Q amplitude from the other antenna is above rssi_or_iq_th
105941d19cfSJiao Xianjun  30|start tx, meanwhile I/Q amplitude from the other antenna is above rssi_or_iq_th
106941d19cfSJiao Xianjun  31|start tx and need for ACK, meanwhile I/Q amplitude from the other antenna is above rssi_or_iq_th
107f71252c5SXianjun Jiao
108f71252c5SXianjun Jiao  To set the RSSI threshold
109f71252c5SXianjun Jiao  ```
110f71252c5SXianjun Jiao  ./side_ch_ctl wh9dY
111f71252c5SXianjun Jiao  ```
112f71252c5SXianjun Jiao  The parameter **Y** specifies the RSSI threshold. Valid range 0 ~ 2047.
113f71252c5SXianjun Jiao
114f71252c5SXianjun Jiao  To set the AGC gain threshold
115f71252c5SXianjun Jiao  ```
116f71252c5SXianjun Jiao  ./side_ch_ctl wh10dY
117f71252c5SXianjun Jiao  ```
118f71252c5SXianjun Jiao  The parameter **Y** specifies the AGC gain threshold. Valid range 0 ~ 127.
119f71252c5SXianjun Jiao
120f71252c5SXianjun Jiao  The command "**side_ch_ctl g**" will perform IQ capture every 100ms until you press ctrl+C. To use a different capture interval:
121f71252c5SXianjun Jiao  ```
122f71252c5SXianjun Jiao  side_ch_ctl gN
123f71252c5SXianjun Jiao  ```
124f71252c5SXianjun Jiao  The interval will become N*1ms
125f71252c5SXianjun Jiao
126f71252c5SXianjun Jiao## Config the iq_len
1279ab264e2SJiao Xianjun  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 independant 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.
128f71252c5SXianjun Jiao  - When insert the kernel module, use:
129f71252c5SXianjun Jiao  ```
130f71252c5SXianjun Jiao  insmod side_ch.ko iq_len_init=3000
131f71252c5SXianjun Jiao  ```
1325deb8d18SXianjun 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.
133f71252c5SXianjun Jiao  - When launch the python script, use:
134f71252c5SXianjun Jiao  ```
135f71252c5SXianjun Jiao  python3 iq_capture.py 3000
136f71252c5SXianjun Jiao  ```
137f71252c5SXianjun Jiao  - When use the matlab script, please change the **iq_len** variable in the script to 3000.
138f71252c5SXianjun Jiao
139f71252c5SXianjun Jiao## Compile the side channel driver and user space program
140f71252c5SXianjun Jiao  - side_ch.ko
141f71252c5SXianjun Jiao  ```
142f71252c5SXianjun Jiao  $OPENWIFI_DIR/driver/side_ch/make_driver.sh $OPENWIFI_DIR $XILINX_DIR ARCH_BIT
143f71252c5SXianjun Jiao(For Zynq 7000, ARCH_BIT should be 32, for Zynq MPSoC, ARCH_BIT should be 64)
144f71252c5SXianjun Jiao  ```
145f71252c5SXianjun Jiao  - side_ch_ctl (take user_space/side_ch_ctl_src/side_ch_ctl.c and compile it on board!)
146f71252c5SXianjun Jiao  ```
147f71252c5SXianjun Jiao  gcc -o side_ch_ctl side_ch_ctl.c
148f71252c5SXianjun Jiao  ```
149f71252c5SXianjun Jiao
150f71252c5SXianjun Jiao## Run the IQ capture together with modes other than monitor
151f71252c5SXianjun 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.
152f71252c5SXianjun Jiao
153f71252c5SXianjun Jiao## Map the IQ information to the WiFi packet
154f71252c5SXianjun 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.
155f71252c5SXianjun Jiao
156f71252c5SXianjun Jiao  Please learn the python and Matlab script to extract IQ information per capture according to your requirement.
157