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 architecture](https://github.com/open-sdr/openwifi/tree/master/doc)] 7 8[Demo [video](https://youtu.be/NpjEaszd5u4). Video [download](https://users.ugent.be/~xjiao/openwifi-low-aac.mp4)] [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 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 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 36* zc706 (Xilinx) + fmcomms2/fmcomms4 (Analog Devices) 37* On roadmap: ADRV9361-Z7035/ADRV9364-Z7020 + ADRV1CRR-BOB (Analog Devices) 38* On roadmap: zcu102 (Xilinx) + fmcomms2/fmcomms4/ADRV9371 (Analog Devices) 39* 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. 40 41**Quick start:** (Example instructions are verified on Ubuntu 16/18) 42 43* Download pre-built [openwifi Linux img file](https://users.ugent.be/~xjiao/openwifi-1.0.0-ghent.zip). Burn the img file to a 16G SD card: 44 45``` 46sudo dd bs=4M if=openwifi-1.0.0-ghent.img of=/dev/mmcblk0 47(mmcblk0 is the dev name of sdcard in Linux. Make sure you use the correct one in your situation!) 48(Above command takes a while) 49``` 50* 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. (For fmcomms4/ad9364, you may connect antennas to TXA/RXA) 51 52* Connect the board to PC. (PC IP address should be 192.168.10.1). Power on the board. Then from PC: 53 54``` 55ssh [email protected] 56(password: openwifi) 57cd openwifi 58service network-manager stop 59./wgd.sh 60(For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1) 61ifconfig sdr0 up 62iwlist sdr0 scan 63(you should see the Wi-Fi scan result) 64``` 65* Setup openwifi hotspot over topology: client -- (sdr0)|board|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet 66 * Enable IPv4 **IP forwarding** on both **board** and **PC** 67 * Then, on board: 68 69 ifconfig sdr0 192.168.13.1 70 route add default gw 192.168.10.1 71 service isc-dhcp-server restart 72 hostapd hostapd-openwifi.conf 73 * Then, on PC: 74 75 sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE 76 sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX 77 * Now you can connect openwifi by your devices (phone, laptop, etc) 78* Connect openwifi to another hotspot. Terminate hostapd, edit wpa-connect.conf properly, then: 79 80 ./wgd.sh 81 (For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1) 82 route del default gw 192.168.10.1 83 wpa_supplicant -i sdr0 -c wpa-connect.conf 84 (Wait for connection done, then open another ssh terminal) 85 dhclient sdr0 86 (Wait for its done, then you should have connection) 87 88* ***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: 89 90 root@analog:~/openwifi# ./sdrctl dev sdr0 get reg rx 20 91 SENDaddr: 00040050 92 reg val: 34be0123 93 (If the last number of reg val is always 3, that means the Viterbi decoder stops working) 94* Real-time control/config via sdrctl (time slice config, etc), please go to openwifi/doc. 95 96**Build openwifi Linux img based on openwifi FPGA and driver:** 97 98* Install Vivado/SDK 2017.4.1 (If you don't need to re-compile FPGA, WebPack version without license is enough) 99* Get pre-built FPGA files from openwifi-hw repository. 100 101``` 102git submodule init openwifi-hw 103git submodule update openwifi-hw 104cd openwifi-hw 105git checkout master 106git pull 107``` 108* Build Linux kernel and modules: 109 110``` 111export XILINX_DIR=your_Xilinx_directory 112cd openwifi 113git submodule init adi-linux 114git submodule update adi-linux 115(Will take a while) 116cd adi-linux 117git reset --hard 4220d5d24c6c7589fc702db4f941f0632b5ad767 118cp ../kernel_boot/kernel_config ./.config 119source $XILINX_DIR/SDK/2017.4/settings64.sh 120export ARCH=arm 121export CROSS_COMPILE=arm-linux-gnueabihf- 122make -j12 UIMAGE_LOADADDR=0x8000 uImage 123(Answer "y" to Xilinx DMA Engines (XILINX_DMA_ENGINES) [N/y/?] (NEW)) 124make modules 125``` 126* Build openwifi Linux driver modules: 127 128``` 129export OPENWIFI_DIR=your_openwifi_directory 130cd $OPENWIFI_DIR/driver 131./make_all.sh $XILINX_DIR/SDK/2017.4/ $OPENWIFI_DIR/adi-linux/ 132``` 133* Build openwifi Linux devicetree: 134 135``` 136cd $OPENWIFI_DIR/kernel_boot 137dtc -I dts -O dtb -o devicetree.dtb devicetree.dts 138``` 139* Build openwifi BOOT.BIN based on FPGA files generated in openwifi-hw: 140 141``` 142cd $OPENWIFI_DIR/kernel_boot 143source $XILINX_DIR/SDK/2017.4/settings64.sh 144./build_boot_bin.sh ../openwifi-hw/zc706_fmcs2/sdk/system_top_hw_platform_0/system.hdf u-boot-zc70x.elf 145(u-boot-zc70x.elf is included in the original Analog Devices Linux img) 146``` 147* 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. 148* 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): 149 150``` 151export SDCARD_DIR=sdcard_mount_point 152cp $OPENWIFI_DIR/kernel_boot/devicetree.dtb $SDCARD_DIR/BOOT 153cp $OPENWIFI_DIR/kernel_boot/output_boot_bin/BOOT.BIN $SDCARD_DIR/BOOT 154cp $OPENWIFI_DIR/adi-linux/arch/arm/boot/uImage $SDCARD_DIR/BOOT 155cd $SDCARD_DIR/BOOT 156sync 157 158sudo mkdir $SDCARD_DIR/rootfs/root/openwifi 159sudo find $OPENWIFI_DIR/driver -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/root/openwifi/ \; 160sudo cp $OPENWIFI_DIR/user_space/* $SDCARD_DIR/rootfs/root/openwifi/ 161 162sudo mkdir $SDCARD_DIR/rootfs/lib/modules 163sudo mkdir $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c 164sudo find $OPENWIFI_DIR/adi-linux -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c/ \; 165sudo rm $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c/{axidmatest.ko,xilinx_dma.ko,adi_axi_hdmi.ko,ad9361_drv.ko} -f 166 167sudo rm $SDCARD_DIR/rootfs/etc/udev/rules.d/70-persistent-net.rules 168sudo cp $OPENWIFI_DIR/kernel_boot/70-persistent-net.rules $SDCARD_DIR/rootfs/etc/udev/rules.d/ 169(Above rule will auto-rename wlan0 to sdr0 which is the openwifi NIC name) 170cd $SDCARD_DIR/rootfs 171sync 172``` 173**Run Linux and do some post-config:** 174 175* 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: 176 177``` 178ln -s /lib/modules/4.14.0-g4220d5d24c6c /lib/modules/4.14.0-g4220d5d 179(in case some Linux use short hash) 180depmod 181(Ignore the error messages) 182modprobe mac80211 183cd openwifi 184./wgd.sh 185(For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1) 186(Wait for the completion) 187ifconfig 188(You should see sdr0 interface) 189iwlist sdr0 scan 190(You should see the Wi-Fi scan results) 191``` 192* Config ssh server and ethernet IP address of the board. In the PC serial console: 193 194``` 195passwd 196(ssh server needs a password, such as "openwifi") 197Add "UseDNS no" to /etc/ssh/sshd_config, otherwise ssh login takes too long time 198Set static IP to board (If you have DHCP server on PC, you can skip this step) 199Add following content to /etc/network/interfaces 200 auto lo eth0 201 iface lo inet loopback 202 iface eth0 inet static 203 address 192.168.10.122 204 netmask 255.255.255.0 205Add following content to /etc/resolv.conf 206 nameserver 8.8.8.8 207 nameserver 4.4.4.4 208 209Disable update (long time hang) on boot or ssh session: 210 sudo chmod -x /etc/update-motd.d/90-updates-available 211 sudo chmod -x /etc/update-motd.d/91-release-upgrade 212 213reboot the board, and set proper IP (192.168.10.1) of the connected PC, then from the PC: 214ssh [email protected] 215(password: openwifi) 216``` 217* Make on board file update easier: 218 * 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: 219 220 mount /dev/mmcblk0p1 /sdcard 221 (Create /sdcard directory firstly if it doesn't exist) 222 cp file /sdcard 223 cd /sdcard 224 sync 225 cd / 226 umount /sdcard 227 (Remember to power cycle the board) 228 * 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: 229 230 ./sdcard_boot_update.sh 231 (Above command downloads uImage, BOOT.BIN and devicetree.dtb, then copy them into boot partition. Remember to power cycle) 232 ./wgd.sh remote 233 (Above command downloads driver files, and brings up sdr0) 234 (For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1) 235 236**Compile sdrctl on the board** ("On the board" means that you login to the board via ssh) 237 238``` 239sudo apt-get install libnl-3-dev 240sudo apt-get install libnl-genl-3-dev 241(Please find the next section to see how to connect board to the internet via your PC) 242(or find out .deb files by above commands and copy .deb to the board, if you do not have internet) 243 244copy $OPENWIFI_DIR/user_space/sdrctl_src to the board, then on the board: 245cd sdrctl_src 246chmod +x version.sh 247make 248``` 249**Internet config** 250* Connect board to internet. Topology: board|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet 251 * Enable IPv4 **IP forwarding** on both **board** and **PC** 252 * On board: 253 ``` 254 route add default gw 192.168.10.1 255 ``` 256 * On PC. After this your board should have internet via NAT through your PC. 257 258 ``` 259 sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE 260 ``` 261* Setup AP for Wi-Fi client. Topology: client -- (sdr0)|board|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet 262 * On board: Install dhcp server preparing for serving your openwifi clients via hostapd. 263 264 ``` 265 sudo apt-get install isc-dhcp-server 266 sudo apt-get install Haveged 267 sudo apt-get install hostapd 268 ``` 269 * Put user_space/dhcpd.conf into (overwrite) /etc/dhcp/dhcpd.conf on board. 270 * On board: 271 272 ``` 273 cd openwifi 274 service network-manager stop 275 ./wgd.sh 276 (For fmcomms4, you need an extra command: ./set_ant.sh rx1 tx1) 277 ifconfig sdr0 up 278 ifconfig sdr0 192.168.13.1 279 route add default gw 192.168.10.1 280 service isc-dhcp-server restart 281 hostapd hostapd-openwifi.conf 282 ``` 283 * On PC: 284 285 ``` 286 sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX 287 ``` 288 * Now you can connect openwifi hotspot from your phone/laptop and access the internet. 289