xref: /openwifi/README.md (revision 89e3e0fbdab78538b43e6492287ee2afd4e86b52)
1# openwifi
2<img src="./openwifi-arch.jpg" width="900">
3
4**openwifi:** Linux mac80211 compatible full-stack IEEE802.11/Wi-Fi design based on SDR (Software Defined Radio).
5
6This repository includes Linux driver and software. [openwifi-hw](https://github.com/open-sdr/openwifi-hw) repository has the FPGA design. [[Detailed document](https://github.com/open-sdr/openwifi/tree/master/doc)]
7
8[Demo [video](https://youtu.be/NpjEaszd5u4) and video [download](https://users.ugent.be/~xjiao/openwifi-low-aac.mp4)]   [openwifi [maillist](https://lists.ugent.be/wws/subscribe/openwifi)] [[Cite openwifi project](#cite-openwifi-project)]
9
10Openwifi code has dual licenses. AGPLv3 is the opensource license. For non-opensource license, please contact [email protected]. Openwifi project also leverages some 3rd party modules. It is user's duty to check and follow licenses of those modules according to the purpose/usage. You can find [an example explanation from Analog Devices](https://github.com/analogdevicesinc/hdl/blob/master/LICENSE) for this compound license conditions.
11
12Openwifi was born in [ORCA project](https://www.orca-project.eu/) (EU's Horizon2020 programme under agreement number 732174).
13
14**Features:**
15
16* 802.11a/g
17* 802.11n MCS 0~7 (Only PHY rx for now. Full system support of 802.11n will come soon)
18* 20MHz bandwidth; 70 MHz to 6 GHz frequency range
19* Mode tested: Ad-hoc; Station; AP, Monitor
20* DCF (CSMA/CA) low MAC layer in FPGA (10us SIFS is achieved)
21* Configurable channel access priority parameters:
22  * duration of RTS/CTS, CTS-to-self
23  * SIFS/DIFS/xIFS/slot-time/CW/etc
24* Time slicing based on MAC address
25* Easy to change bandwidth and frequency:
26  * 2MHz for 802.11ah in sub-GHz
27  * 10MHz for 802.11p/vehicle in 5.9GHz
28* On roadmap: **802.11ax**
29
30**Performance (AP: openwifi at channel 44, client: TL-WDN4200 N900 Wireless Dual Band USB Adapter. iperf test):**
31* AP --> client: 30.6Mbps(TCP), 38.8Mbps(UDP)
32* client --> AP: 17.0Mbps(TCP), 21.5Mbps(UDP)
33
34**Supported SDR platforms:**
35
36board_name|actual boards used|status
37-------|-------|----
38zc706_fmcs2|Xilinx ZC706 dev board + FMCOMMS2/3/4|done
39adrv9361z7035|ADRV9361Z7035 SOM + ADRV1CRR-BOB carrier board|done. wait for test
40adrv9361z7035_fmc|ADRV9361Z7035 SOM + ADRV1CRR-FMC carrier board|done
41adrv9364z7020|ADRV9364Z7020 SOM + ADRV1CRR-BOB carrier board|future
42zcu102_fmcs2|Xilinx ZCU102 dev board + FMCOMMS2/3/4|future
43zcu102_9371|Xilinx ZCU102 dev board + ADRV9371|future
44
45* board_name is used to identify FPGA design in openwifi-hw/boards/ and rf script in user_space/rf_init_board_name.sh
46* Don't have any boards? Or you like JTAG boot instead of SD card? Check our test bed [w-iLab.t](https://doc.ilabt.imec.be/ilabt/wilab/tutorials/openwifi.html) tutorial.
47
48**Quick start:** (Example instructions are verified on Ubuntu 16/18)
49
50* Download pre-built [openwifi Linux img file](https://users.ugent.be/~xjiao/openwifi-1.0.0-ghent.zip) (depends on board_name as well). Burn the img file to a 16G SD card:
51```
52sudo dd bs=4M if=openwifi-1.0.0-ghent.img of=/dev/mmcblk0
53(mmcblk0 is the dev name of sdcard in Linux. Make sure you use the correct one in your situation!)
54(Above command takes a while)
55```
56* Connect RX/TX antenna to RX1A/TX2A ports(For fmcomms4/ad9364, you may connect antennas to TXA/RXA), and make two antennas orthogonal to each other for good isolation. Config the board to SD card boot mode by switches (Read the board spec on internet). Insert the SD card to the board.
57
58* Connect the board to PC. (PC IP address should be 192.168.10.1). Power on the board. Then from PC:
59```
60ssh [email protected]
61(password: openwifi)
62cd openwifi
63cp rf_init_board_name.sh rf_init.sh
64(If there isn't rf_init.sh, rename your board rf script, such as rf_init_adrv9361z7035.sh, to rf_init.sh for wgd.sh to call)
65service network-manager stop
66./wgd.sh
67(For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1)
68ifconfig sdr0 up
69iwlist sdr0 scan
70(you should see the Wi-Fi scan result)
71```
72* Setup openwifi hotspot over topology: client -- (sdr0)|board|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet
73  * Enable IPv4 **IP forwarding** on both **board** and **PC**
74  * Then, on board:
75
76        ifconfig sdr0 192.168.13.1
77        route add default gw 192.168.10.1
78        service isc-dhcp-server restart
79        hostapd hostapd-openwifi.conf
80  * Then, on PC:
81
82        sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE
83        sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
84  * Now you can connect openwifi by your devices (phone, laptop, etc)
85* Connect openwifi to another hotspot. Terminate hostapd, edit wpa-connect.conf properly, then:
86
87        ./wgd.sh
88        (For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1)
89        route del default gw 192.168.10.1
90        wpa_supplicant -i sdr0 -c wpa-connect.conf
91        (Wait for connection done, then open another ssh terminal)
92        dhclient sdr0
93        (Wait for its done, then you should have connection)
94
95* Real-time control/config via "sdrctl" (register, time slice config, etc), please go to openwifi/doc.
96
97* ***Note***: The files (BOOT.BIN, drivers, etc) in pre-built SD card img might not have the latest bug-fixes/features. Check related section in this README on how to generate them and update them if needed.
98
99* ***Note***: If openwifi stops working after ~2 hours, it means the evaluation license of Xilinx Viterbi decoder has expired. You need to power cycle the board. Run this command several times on board to confirm:
100
101        root@analog:~/openwifi# ./sdrctl dev sdr0 get reg rx 20
102        SENDaddr: 00040050
103        reg  val: 34be0123
104        (If the last number of reg val is always 3, that means the Viterbi decoder stops working)
105
106**Build openwifi Linux img based on openwifi FPGA and driver:**
107
108* Install Vivado/SDK 2017.4.1 (If you don't need to re-compile FPGA, WebPack version without license is enough)
109* Get pre-built FPGA files from openwifi-hw repository.
110```
111git submodule init openwifi-hw
112git submodule update openwifi-hw
113cd openwifi-hw
114git checkout master
115git pull
116```
117* Build Linux kernel and modules:
118```
119export XILINX_DIR=your_Xilinx_directory
120cd openwifi
121git submodule init adi-linux
122git submodule update adi-linux
123(Will take a while)
124cd adi-linux
125git reset --hard 4220d5d24c6c7589fc702db4f941f0632b5ad767
126cp ../kernel_boot/kernel_config ./.config
127source $XILINX_DIR/SDK/2017.4/settings64.sh
128export ARCH=arm
129export CROSS_COMPILE=arm-linux-gnueabihf-
130make -j12 UIMAGE_LOADADDR=0x8000 uImage
131(Answer "y" to Xilinx DMA Engines (XILINX_DMA_ENGINES) [N/y/?] (NEW))
132make modules
133```
134* Build openwifi Linux driver modules:
135```
136export OPENWIFI_DIR=your_openwifi_directory
137cd $OPENWIFI_DIR/driver
138./make_all.sh $XILINX_DIR/SDK/2017.4/ $OPENWIFI_DIR/adi-linux/
139```
140* Build openwifi Linux devicetree:
141```
142export BOARD_NAME=your_board_name
143(Check the board_name in the table of supported SDR platforms)
144cd $OPENWIFI_DIR/kernel_boot/boards/$BOARD_NAME
145dtc -I dts -O dtb -o devicetree.dtb devicetree.dts
146cp devicetree.dtb $OPENWIFI_DIR/kernel_boot/
147```
148* Build openwifi BOOT.BIN based on FPGA files generated in openwifi-hw:
149```
150cd $OPENWIFI_DIR/kernel_boot
151source $XILINX_DIR/SDK/2017.4/settings64.sh
152./build_boot_bin.sh ../openwifi-hw/boards/$BOARD_NAME/sdk/system_top_hw_platform_0/system.hdf ./boards/$BOARD_NAME/u-boot.elf
153(u-boot.elf is renamed from the compressed file in the board directory of original Analog Devices SD card boot partition)
154```
155* Prepare correct rf_init.sh in host openwifi/user_space
156```
157cd $OPENWIFI_DIR/user_space
158cp rf_init_board_name.sh rf_init.sh
159(If there isn't rf_init.sh, rename your board rf script, such as rf_init_adrv9361z7035.sh, to rf_init.sh for "wgd.sh remote" to download)
160```
161* Download [2017_R1-2018_01_29.img.xz](http://swdownloads.analog.com/cse/2017_R1-2018_01_29.img.xz) from [Analog Devices Wiki](https://wiki.analog.com/resources/tools-software/linux-software/zynq_images). Burn it into a SD card via your PC.
162* Mount SD card BOOT/rootfs partitions to SDCARD_DIR directory of your PC (If it is mounted automatically, find the directory). Then copy built files to SD card via your PC. (You can also update files over ftp/ssh after your full system runs. Please check next section. Read carefully user_space/sdcard_boot_update.sh and set your ftp root directory to $OPENWIFI_DIR in your PC):
163```
164export SDCARD_DIR=sdcard_mount_point
165cp $OPENWIFI_DIR/kernel_boot/boards/$BOARD_NAME/devicetree.dtb $SDCARD_DIR/BOOT
166cp $OPENWIFI_DIR/kernel_boot/output_boot_bin/BOOT.BIN $SDCARD_DIR/BOOT
167cp $OPENWIFI_DIR/adi-linux/arch/arm/boot/uImage $SDCARD_DIR/BOOT
168cd $SDCARD_DIR/BOOT
169sync
170
171sudo mkdir $SDCARD_DIR/rootfs/root/openwifi
172sudo find $OPENWIFI_DIR/driver -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/root/openwifi/ \;
173sudo cp $OPENWIFI_DIR/user_space/* $SDCARD_DIR/rootfs/root/openwifi/ -rf
174
175sudo mkdir $SDCARD_DIR/rootfs/lib/modules
176sudo mkdir $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d
177sudo find $OPENWIFI_DIR/adi-linux -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d/ \;
178sudo rm $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d/{axidmatest.ko,xilinx_dma.ko,adi_axi_hdmi.ko,ad9361_drv.ko} -f
179
180sudo rm $SDCARD_DIR/rootfs/etc/udev/rules.d/70-persistent-net.rules
181sudo cp $OPENWIFI_DIR/kernel_boot/70-persistent-net.rules $SDCARD_DIR/rootfs/etc/udev/rules.d/
182(Above rule will auto-rename wlan0 to sdr0 which is the openwifi NIC name)
183cd $SDCARD_DIR/rootfs
184sync
185```
186**Run Linux and do some post-config:**
187
188* Insert the SD card to the board, power on and run serial console (such as minicom) from a PC via USB-UART cable to the board. After booting completes, in the PC serial console:
189```
190depmod
191(Ignore the error messages)
192modprobe mac80211
193(if you get error like: could not open moddep file 'lib/modules/4.14.0XXXYYYZZZ/modules.dep.bin', you could make a symbol link and modprobe again)
194ln -s /lib/modules/4.14.0-g4220d5d /lib/modules/4.14.0XXXYYYZZZ
195depmod
196modprobe mac80211
197
198cd openwifi
199cp rf_init_board_name.sh rf_init.sh
200(rename your board rf script, such as rf_init_adrv9361z7035.sh, to rf_init.sh for wgd.sh to call)
201./wgd.sh
202(For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1)
203(Wait for the completion)
204ifconfig
205(You should see sdr0 interface)
206iwlist sdr0 scan
207(You should see the Wi-Fi scan results)
208```
209* Config ssh server and ethernet IP address of the board. In the PC serial console:
210```
211passwd
212(ssh server needs a password, such as "openwifi")
213Add "UseDNS no" to /etc/ssh/sshd_config, otherwise ssh login takes too long time
214Set static IP to board (If you have DHCP server on PC, you can skip this step)
215Add following content to /etc/network/interfaces
216  auto lo eth0
217  iface lo inet loopback
218  iface eth0 inet static
219          address 192.168.10.122
220          netmask 255.255.255.0
221Add following content to /etc/resolv.conf
222  nameserver 8.8.8.8
223  nameserver 4.4.4.4
224
225Disable update (long time hang) on boot or ssh session:
226  sudo chmod -x /etc/update-motd.d/90-updates-available
227  sudo chmod -x /etc/update-motd.d/91-release-upgrade
228
229reboot the board, and set proper IP (192.168.10.1) of the connected PC, then from the PC:
230ssh [email protected]
231(password: openwifi)
232```
233* Make on board file update easier:
234  * Option 1: Access the board disk/rootfs from Ubuntu PC: "File manager --> Connect to Server...", input: sftp://[email protected]/root . Then you can operate files on board like normal files on your disk. To update files that need to be in boot partition (BOOT.BIN, uImage and devicetree.dtb), you can transfer those files to rootfs firstly, then on board:
235
236         mount /dev/mmcblk0p1 /sdcard
237         (Create /sdcard directory firstly if it doesn't exist)
238         cp file /sdcard
239         cd /sdcard
240         sync
241         cd /
242         umount /sdcard
243         (Remember to power cycle the board)
244  * Option 2: Setup [ftp server](https://help.ubuntu.com/lts/serverguide/ftp-server.html) on PC, allow anonymous and change ftp root directory to $OPENWIFI_DIR. Then on board:
245
246        ./sdcard_boot_update.sh
247        (Above command downloads uImage, BOOT.BIN and devicetree.dtb, then copy them into boot partition. Remember to power cycle)
248        ./wgd.sh remote
249        (Above command downloads driver files, and brings up sdr0)
250        (For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1)
251
252**Compile sdrctl on the board** ("On the board" means that you login to the board via ssh)
253```
254sudo apt-get install libnl-3-dev
255sudo apt-get install libnl-genl-3-dev
256(Please find the next section to see how to connect board to the internet via your PC)
257(or find out .deb files by above commands and copy .deb to the board, if you do not have internet)
258
259copy $OPENWIFI_DIR/user_space/sdrctl_src to the board, then on the board:
260cd sdrctl_src
261chmod +x version.sh
262make
263```
264
265**Internet config**
266* Connect board to internet. Topology: board|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet
267  * Enable IPv4 **IP forwarding** on both **board** and **PC**
268  * On board:
269  ```
270  route add default gw 192.168.10.1
271  ```
272  * On PC. After this your board should have internet via NAT through your PC.
273
274  ```
275  sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE
276  ```
277* Setup AP for Wi-Fi client. Topology: client -- (sdr0)|board|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet
278  * On board: Install dhcp server preparing for serving your openwifi clients via hostapd.
279  ```
280  sudo apt-get install isc-dhcp-server
281  sudo apt-get install Haveged
282  sudo apt-get install hostapd
283  ```
284  * Put user_space/dhcpd.conf into (overwrite) /etc/dhcp/dhcpd.conf on board.
285  * On board:
286  ```
287  cd openwifi
288  service network-manager stop
289  ./wgd.sh
290  (For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1)
291  ifconfig sdr0 up
292  ifconfig sdr0 192.168.13.1
293  route add default gw 192.168.10.1
294  service isc-dhcp-server restart
295  hostapd hostapd-openwifi.conf
296  ```
297  * On PC:
298  ```
299  sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
300  ```
301  * Now you can connect openwifi hotspot from your phone/laptop and access the internet.
302
303**Connecting a client to openwifi AP in 2.4GHz**
304
305Openwifi only applies OFDM as its modulation scheme and as a result, it is not backward compatible with 802.11b clients or modes of operation. This is usually the case during beacon transmission, connection establishment, and robust communication.
306
307As a solution to this problem, openwifi can be fully controlled only if communicating with APs/clients instantiated using hostapd/wpa_supplicant userspace programs respectively.
308
309For hostapd program, 802.11b rates can be suppressed using configuration commands (i.e. supported_rates, basic_rates) and an example configuration file is provided (i.e. hostapd-openwifi.conf). One small caveat to this one comes from fullMAC Wi-Fi cards as they must implement the *NL80211_TXRATE_LEGACY* NetLink handler at the device driver level.
310
311On the other hand, the wpa_supplicant program on the client side (commercial Wi-Fi dongle/board) cannot suppress 802.11b rates out of the box in 2.4GHz band, so there will be an issue when connecting openwifi (OFDM only). A patched wpa_supplicant should be used at the client side.
312```
313cd openwifi/user_space
314wget http://w1.fi/releases/wpa_supplicant-2.1.tar.gz
315tar xzvf wpa_supplicant-2.1.tar.gz
316patch -d wpa_supplicant-2.1/src/drivers/ < driver_nl80211.patch
317cd wpa_supplicant-2.1/wpa_supplicant/
318cp defconfig .config
319sed -i 's/#CONFIG_LIBNL32.*/CONFIG_LIBNL32=y/g' .config
320make -j16
321sudo make install
322cd ../../
323rm -r wpa_supplicant-2.1/ wpa_supplicant-2.1.tar.gz
324```
325
326## cite openwifi project
327
328Any use of openwifi project which results in a publication should include a citation via (bibtex example):
329```
330@electronic{openwifigithub,
331            author = {Xianjun, Jiao and Wei, Liu and Michael, Mehari},
332            title = {open-source IEEE802.11/Wi-Fi baseband chip/FPGA design},
333            url = {https://github.com/open-sdr/openwifi},
334            year = {2019},
335}
336```
337