xref: /openwifi/README.md (revision 14124d7306727ee7bbae83655e3d9ecacc4c3bee)
1# openwifi
2<img src="./openwifi-arch.jpg" width="900">
3
4**openwifi:** Linux mac80211 compatiable full-stack Wi-Fi design based on SDR (Software Defined Radio).
5
6This repository includes Linux driver and software. [openwifi-hw](https://github.ugent.be/xjiao/openwifi-hw) repository has the FPGA design. [[Detailed architecture](https://github.ugent.be/xjiao/openwifi/tree/master/doc)]
7
8[Demo [video](https://drive.google.com/file/d/1Qk-MEHkK_9yL_KPv--4MCJhLoGzE2N5W/view?usp=sharing)]. [openwifi [maillist](https://lists.ugent.be/wws/subscribe/openwifi)]
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 your duty to check and follow licenses of those modules according to your purpose. 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; 802.11n MCS 0~7; 20MHz
17* Mode tested: Ad-hoc; Station; AP
18* DCF (CSMA/CA) low MAC layer in FPGA
19* Configurable channel access priority parameters:
20  * duration of RTS/CTS, CTS-to-self
21  * SIFS/DIFS/xIFS/slot-time/CW/etc
22* Time slicing based on MAC address
23* Easy to change bandwidth and frequency:
24  * 2MHz for 802.11ah in sub-GHz
25  * 10MHz for 802.11p/vehicle in 5.9GHz
26* On roadmap: **802.11ax**
27
28**Performance (AP: openwifi at channel 44, client: TL-WDN4200 N900 Wireless Dual Band USB Adapter. iperf test):**
29* AP --> client: 30.6Mbps(TCP), 38.8Mbps(UDP)
30* client --> AP: 17.0Mbps(TCP), 21.5Mbps(UDP)
31
32**Supported SDR platforms:**
33
34* zc706 (Xilinx) + fmcomms2 (Analog Devices)
35* On roadmap: ADRV9361-Z7035/ADRV9364-Z7020 + ADRV1CRR-BOB (Analog Devices)
36* On roadmap: zcu102 (Xilinx) + fmcomms2/ADRV9371 (Analog Devices)
37* 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.
38
39**Quick start:** (Example instructions are verified on Ubuntu 16/18)
40
41* Download pre-built [openwifi Linux img file](https://users.ugent.be/~xjiao/). Burn the img file to a 16G SD card:
42
43```
44sudo dd bs=4M if=openwifi-zc706-v000.img of=/dev/mmcblk0
45(mmcblk0 is the dev name of sdcard in Linux. Make sure you use the correct one in your situation!)
46(Above command takes a while)
47```
48* Connect RX/TX antenna to RX1A/TX2A ports of your zc706+fmcomms2 platform, and make two antennas orthogonal to each other for good isolation. Config zc706 to SD card boot mode by switches (Read zc706 board spec on internet). Insert the SD card to zc706.
49
50* Connect the board to PC. (PC IP address should be 192.168.10.1). Power on the board. Then from PC:
51
52```
53ssh [email protected]
54(password: openwifi)
55cd openwifi
56service network-manager stop
57./wgd.sh
58ifconfig sdr0 up
59iwlist sdr0 scan
60(you should see the Wi-Fi scan result)
61```
62* Setup openwifi hotspot over topology: client -- (sdr0)|zc706|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet
63  * Enable IPv4 IP forwarding on both zc706 and PC
64  * Then, on board:
65
66        ifconfig sdr0 192.168.13.1
67        route add default gw 192.168.10.1
68        service isc-dhcp-server restart
69        hostapd hostapd-openwifi.conf
70  * Then, on PC:
71
72        sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE
73        sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
74  * Now you can connect openwifi by your devices (phone, laptop, etc)
75* Connect openwifi to another hotspot. Terminate hostapd, edit wpa-connect.conf properly, then:
76
77        ./wgd.sh
78        route del default gw 192.168.10.1
79        wpa_supplicant -i sdr0 -c wpa-connect.conf
80        (Wait for connection done, then open another ssh terminal)
81        dhclient sdr0
82        (Wait for its donw, then you should have connection)
83
84* ***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:
85
86        root@analog:~/openwifi# ./sdrctl dev sdr0 get reg rx 20
87        SENDaddr: 00040050
88        reg  val: 34be0123
89        (If the last number of reg val is always 3, that means the Viterbi decoder stops working)
90* Real-time control/config via sdrctl (time slice config, etc), please find the [doc](https://github.ugent.be/xjiao/openwifi/tree/master/doc).
91
92**Build openwifi Linux img based on openwifi FPGA and driver:**
93
94* Install Vivado/SDK 2017.4.1.
95* Get necessary FPGA files from openwifi-hw repository.
96
97```
98git submodule init openwifi-hw
99git submodule update openwifi-hw
100cd openwifi-hw
101git pull
102```
103* Build Linux kernel and modules:
104
105```
106export XILINX_DIR=your_Xilinx_directory
107cd openwifi
108git submodule init adi-linux
109git submodule update adi-linux
110(Will take a while)
111cd adi-linux
112git reset --hard 4220d5d24c6c7589fc702db4f941f0632b5ad767
113cp ../kernel_boot/kernel_config ./.config
114source $XILINX_DIR/SDK/2017.4/settings64.sh
115export ARCH=arm
116export CROSS_COMPILE=arm-linux-gnueabihf-
117make -j12 UIMAGE_LOADADDR=0x8000 uImage
118(Answer "y" to Xilinx DMA Engines (XILINX_DMA_ENGINES) [N/y/?] (NEW))
119make modules
120```
121* Build openwifi Linux driver modules:
122
123```
124export OPENWIFI_DIR=your_openwifi_directory
125cd $OPENWIFI_DIR/driver
126./make_all.sh $XILINX_DIR/SDK/2017.4/ $OPENWIFI_DIR/adi-linux/
127```
128* Build openwifi Linux devicetree:
129
130```
131cd $OPENWIFI_DIR/kernel_boot
132dtc -I dts -O dtb -o devicetree.dtb devicetree.dts
133```
134* Build openwifi BOOT.BIN based on FPGA files generated in openwifi-hw:
135
136```
137cd $OPENWIFI_DIR/kernel_boot
138source $XILINX_DIR/Vivado/2017.4/settings64.sh
139./build_boot_bin.sh ../openwifi-hw/zc706_fmcs2/sdk/system_top_hw_platform_0/system.hdf u-boot-zc70x.elf
140(u-boot-zc70x.elf is included in the original Analog Devices Linux img)
141```
142* 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.
143* 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 user_space/sdcard_boot_update.sh and set your ftp root directory to openwifi repository in your PC):
144
145```
146export SDCARD_DIR=sdcard_mount_point
147cp $OPENWIFI_DIR/kernel_boot/devicetree.dtb $SDCARD_DIR/BOOT
148cp $OPENWIFI_DIR/kernel_boot/output_boot_bin/BOOT.BIN $SDCARD_DIR/BOOT
149cp $OPENWIFI_DIR/adi-linux/arch/arm/boot/uImage $SDCARD_DIR/BOOT
150cd $SDCARD_DIR/BOOT
151sync
152
153sudo mkdir $SDCARD_DIR/rootfs/root/openwifi
154sudo find $OPENWIFI_DIR/driver -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/root/openwifi/ \;
155sudo cp $OPENWIFI_DIR/user_space/* $SDCARD_DIR/rootfs/root/openwifi/
156
157sudo mkdir $SDCARD_DIR/rootfs/lib/modules
158sudo mkdir $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c
159sudo find $OPENWIFI_DIR/adi-linux -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c/ \;
160sudo rm $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c/{axidmatest.ko,xilinx_dma.ko,adi_axi_hdmi.ko,ad9361_drv.ko} -f
161
162sudo rm $SDCARD_DIR/rootfs/etc/udev/rules.d/70-persistent-net.rules
163sudo cp $OPENWIFI_DIR/kernel_boot/70-persistent-net.rules $SDCARD_DIR/rootfs/etc/udev/rules.d/
164(Above rule will auto-rename wlan0 to sdr0 which is the openwifi NIC name)
165cd $SDCARD_DIR/rootfs
166sync
167```
168**Run Linux and do some post-config:**
169
170* 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:
171
172```
173ln -s /lib/modules/4.14.0-g4220d5d24c6c /lib/modules/4.14.0-g4220d5d
174(in case some Linux use short hash)
175depmod
176(Ignore the error messages)
177modprobe mac80211
178cd openwifi
179./wgd.sh
180(Wait for the completion)
181ifconfig
182(You should see sdr0 interface)
183iwlist sdr0 scan
184(You should see the Wi-Fi scan results)
185```
186* Config ssh server and ethernet IP address of the board. In the PC serial console:
187
188```
189passwd
190(ssh server needs a password, such as "openwifi")
191Add "UseDNS no" to /etc/ssh/sshd_config, otherwise ssh login takes too long time
192Set static IP to board (If you have DHCP server on PC, you can skip this step)
193Add following content to /etc/network/interfaces
194  auto lo eth0
195  iface lo inet loopback
196  iface eth0 inet static
197          address 192.168.10.122
198          netmask 255.255.255.0
199Add following content to /etc/resolv.conf
200  nameserver 8.8.8.8
201  nameserver 4.4.4.4
202
203Disable update (long time hang) on boot or ssh session:
204  sudo chmod -x /etc/update-motd.d/90-updates-available
205  sudo chmod -x /etc/update-motd.d/91-release-upgrade
206
207reboot the board, and set proper IP of the connected PC, then from the PC:
208ssh [email protected]
209(password: openwifi)
210
211Access the board disk from PC: Ubuntu "File manager --> Connect to Server...", input: sftp://[email protected]/root
212
213./wgd.sh remote
214(Above command updates files from your PC and brings up sdr0. Make sure set ftp root directory to openwifi repository in your PC)
215```
216**Compile user_space/sdrctl_src on the board** ("On the board" means that you login to the board via ssh)
217
218```
219sudo apt-get install libnl-3-dev
220sudo apt-get install libnl-genl-3-dev
221(or find out .deb files by above commands and copy .deb to the board, if you do not have internet)
222
223copy user_space/sdrctl_src to the board, then on the board:
224cd sdrctl_src
225chmod +x version.sh
226make
227```
228**Internet config**
229
230* Topology: client -- (sdr0)|zc706|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet
231* Enable IPv4 IP forwarding on both zc706 and PC
232* On PC. After this your board should have internet via NAT through your PC.
233
234```
235sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE
236```
237* On board: Install dhcp server preparing for serving your openwifi clients via hostapd.
238
239```
240sudo apt-get install isc-dhcp-server
241sudo apt-get install Haveged
242```
243* Put user_space/dhcpd.conf into (overwrite) /etc/dhcp/dhcpd.conf on board.
244
245* On board:
246
247```
248cd openwifi
249service network-manager stop
250./wgd.sh
251ifconfig sdr0 up
252ifconfig sdr0 192.168.13.1
253route add default gw 192.168.10.1
254service isc-dhcp-server restart
255hostapd hostapd-openwifi.conf
256```
257* On PC:
258
259```
260sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX
261```
262* Now you can connect openwifi hotspot from your phone/laptop and access internet.
263