10df4ca4dSimoerman# openwifi 22ee67178SXianjun Jiao<img src="./openwifi-arch.jpg" width="900"> 32ee67178SXianjun Jiao 42ee67178SXianjun Jiao**openwifi:** Linux mac80211 compatiable full-stack Wi-Fi design based on SDR (Software Defined Radio). 52ee67178SXianjun Jiao 6eb247655SJiao XianjunThis 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)] 72ee67178SXianjun Jiao 8eb247655SJiao Xianjun[Demo [video](https://users.ugent.be/~xjiao/openwifi.mp4)]. [openwifi [maillist](https://lists.ugent.be/wws/subscribe/openwifi)] 92ee67178SXianjun Jiao 102ee67178SXianjun JiaoOpenwifi 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. 112ee67178SXianjun Jiao 122ee67178SXianjun JiaoOpenwifi was born in [ORCA project](https://www.orca-project.eu/) (EU's Horizon2020 programme under agreement number 732174). 132ee67178SXianjun Jiao 142ee67178SXianjun Jiao**Features:** 152ee67178SXianjun Jiao 162ee67178SXianjun Jiao* 802.11a/g; 802.11n MCS 0~7; 20MHz 172ee67178SXianjun Jiao* Mode tested: Ad-hoc; Station; AP 182ee67178SXianjun Jiao* DCF (CSMA/CA) low MAC layer in FPGA 192ee67178SXianjun Jiao* Configurable channel access priority parameters: 202ee67178SXianjun Jiao * duration of RTS/CTS, CTS-to-self 212ee67178SXianjun Jiao * SIFS/DIFS/xIFS/slot-time/CW/etc 222ee67178SXianjun Jiao* Time slicing based on MAC address 232ee67178SXianjun Jiao* Easy to change bandwidth and frequency: 242ee67178SXianjun Jiao * 2MHz for 802.11ah in sub-GHz 252ee67178SXianjun Jiao * 10MHz for 802.11p/vehicle in 5.9GHz 262ee67178SXianjun Jiao* On roadmap: **802.11ax** 272ee67178SXianjun Jiao 282ee67178SXianjun Jiao**Performance (AP: openwifi at channel 44, client: TL-WDN4200 N900 Wireless Dual Band USB Adapter. iperf test):** 292ee67178SXianjun Jiao* AP --> client: 30.6Mbps(TCP), 38.8Mbps(UDP) 302ee67178SXianjun Jiao* client --> AP: 17.0Mbps(TCP), 21.5Mbps(UDP) 312ee67178SXianjun Jiao 322ee67178SXianjun Jiao**Supported SDR platforms:** 332ee67178SXianjun Jiao 342ee67178SXianjun Jiao* zc706 (Xilinx) + fmcomms2 (Analog Devices) 352ee67178SXianjun Jiao* On roadmap: ADRV9361-Z7035/ADRV9364-Z7020 + ADRV1CRR-BOB (Analog Devices) 362ee67178SXianjun Jiao* On roadmap: zcu102 (Xilinx) + fmcomms2/ADRV9371 (Analog Devices) 372ee67178SXianjun Jiao* 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. 382ee67178SXianjun Jiao 392ee67178SXianjun Jiao**Quick start:** (Example instructions are verified on Ubuntu 16/18) 402ee67178SXianjun Jiao 41eb247655SJiao Xianjun* 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: 422ee67178SXianjun Jiao 432ee67178SXianjun Jiao``` 442ee67178SXianjun Jiaosudo dd bs=4M if=openwifi-zc706-v000.img of=/dev/mmcblk0 452ee67178SXianjun Jiao(mmcblk0 is the dev name of sdcard in Linux. Make sure you use the correct one in your situation!) 462ee67178SXianjun Jiao(Above command takes a while) 472ee67178SXianjun Jiao``` 482ee67178SXianjun Jiao* 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. 492ee67178SXianjun Jiao 502ee67178SXianjun Jiao* Connect the board to PC. (PC IP address should be 192.168.10.1). Power on the board. Then from PC: 512ee67178SXianjun Jiao 522ee67178SXianjun Jiao``` 532ee67178SXianjun Jiaossh [email protected] 542ee67178SXianjun Jiao(password: openwifi) 552ee67178SXianjun Jiaocd openwifi 562ee67178SXianjun Jiaoservice network-manager stop 572ee67178SXianjun Jiao./wgd.sh 582ee67178SXianjun Jiaoifconfig sdr0 up 592ee67178SXianjun Jiaoiwlist sdr0 scan 602ee67178SXianjun Jiao(you should see the Wi-Fi scan result) 612ee67178SXianjun Jiao``` 622ee67178SXianjun Jiao* Setup openwifi hotspot over topology: client -- (sdr0)|zc706|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet 632ee67178SXianjun Jiao * Enable IPv4 IP forwarding on both zc706 and PC 642ee67178SXianjun Jiao * Then, on board: 652ee67178SXianjun Jiao 662ee67178SXianjun Jiao ifconfig sdr0 192.168.13.1 672ee67178SXianjun Jiao route add default gw 192.168.10.1 682ee67178SXianjun Jiao service isc-dhcp-server restart 692ee67178SXianjun Jiao hostapd hostapd-openwifi.conf 702ee67178SXianjun Jiao * Then, on PC: 712ee67178SXianjun Jiao 722ee67178SXianjun Jiao sudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE 732ee67178SXianjun Jiao sudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX 742ee67178SXianjun Jiao * Now you can connect openwifi by your devices (phone, laptop, etc) 752ee67178SXianjun Jiao* Connect openwifi to another hotspot. Terminate hostapd, edit wpa-connect.conf properly, then: 762ee67178SXianjun Jiao 772ee67178SXianjun Jiao ./wgd.sh 782ee67178SXianjun Jiao route del default gw 192.168.10.1 792ee67178SXianjun Jiao wpa_supplicant -i sdr0 -c wpa-connect.conf 802ee67178SXianjun Jiao (Wait for connection done, then open another ssh terminal) 812ee67178SXianjun Jiao dhclient sdr0 822ee67178SXianjun Jiao (Wait for its donw, then you should have connection) 832ee67178SXianjun Jiao 842ee67178SXianjun Jiao* ***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: 852ee67178SXianjun Jiao 862ee67178SXianjun Jiao root@analog:~/openwifi# ./sdrctl dev sdr0 get reg rx 20 872ee67178SXianjun Jiao SENDaddr: 00040050 882ee67178SXianjun Jiao reg val: 34be0123 892ee67178SXianjun Jiao (If the last number of reg val is always 3, that means the Viterbi decoder stops working) 90eb247655SJiao Xianjun* Real-time control/config via sdrctl (time slice config, etc), please go to openwifi/doc. 912ee67178SXianjun Jiao 922ee67178SXianjun Jiao**Build openwifi Linux img based on openwifi FPGA and driver:** 932ee67178SXianjun Jiao 942ee67178SXianjun Jiao* Install Vivado/SDK 2017.4.1. 952ee67178SXianjun Jiao* Get necessary FPGA files from openwifi-hw repository. 962ee67178SXianjun Jiao 972ee67178SXianjun Jiao``` 982ee67178SXianjun Jiaogit submodule init openwifi-hw 992ee67178SXianjun Jiaogit submodule update openwifi-hw 1002ee67178SXianjun Jiaocd openwifi-hw 10196be0adbSJiao Xianjungit checkout master 1022ee67178SXianjun Jiaogit pull 1032ee67178SXianjun Jiao``` 1042ee67178SXianjun Jiao* Build Linux kernel and modules: 1052ee67178SXianjun Jiao 1062ee67178SXianjun Jiao``` 1072ee67178SXianjun Jiaoexport XILINX_DIR=your_Xilinx_directory 1082ee67178SXianjun Jiaocd openwifi 1092ee67178SXianjun Jiaogit submodule init adi-linux 1102ee67178SXianjun Jiaogit submodule update adi-linux 1112ee67178SXianjun Jiao(Will take a while) 1122ee67178SXianjun Jiaocd adi-linux 1132ee67178SXianjun Jiaogit reset --hard 4220d5d24c6c7589fc702db4f941f0632b5ad767 1142ee67178SXianjun Jiaocp ../kernel_boot/kernel_config ./.config 1152ee67178SXianjun Jiaosource $XILINX_DIR/SDK/2017.4/settings64.sh 1162ee67178SXianjun Jiaoexport ARCH=arm 1172ee67178SXianjun Jiaoexport CROSS_COMPILE=arm-linux-gnueabihf- 1182ee67178SXianjun Jiaomake -j12 UIMAGE_LOADADDR=0x8000 uImage 1192ee67178SXianjun Jiao(Answer "y" to Xilinx DMA Engines (XILINX_DMA_ENGINES) [N/y/?] (NEW)) 1202ee67178SXianjun Jiaomake modules 1212ee67178SXianjun Jiao``` 1222ee67178SXianjun Jiao* Build openwifi Linux driver modules: 1232ee67178SXianjun Jiao 1242ee67178SXianjun Jiao``` 1252ee67178SXianjun Jiaoexport OPENWIFI_DIR=your_openwifi_directory 1262ee67178SXianjun Jiaocd $OPENWIFI_DIR/driver 1272ee67178SXianjun Jiao./make_all.sh $XILINX_DIR/SDK/2017.4/ $OPENWIFI_DIR/adi-linux/ 1282ee67178SXianjun Jiao``` 1292ee67178SXianjun Jiao* Build openwifi Linux devicetree: 1302ee67178SXianjun Jiao 1312ee67178SXianjun Jiao``` 1322ee67178SXianjun Jiaocd $OPENWIFI_DIR/kernel_boot 1332ee67178SXianjun Jiaodtc -I dts -O dtb -o devicetree.dtb devicetree.dts 1342ee67178SXianjun Jiao``` 1352ee67178SXianjun Jiao* Build openwifi BOOT.BIN based on FPGA files generated in openwifi-hw: 1362ee67178SXianjun Jiao 1372ee67178SXianjun Jiao``` 1382ee67178SXianjun Jiaocd $OPENWIFI_DIR/kernel_boot 1392ee67178SXianjun Jiaosource $XILINX_DIR/Vivado/2017.4/settings64.sh 1402ee67178SXianjun Jiao./build_boot_bin.sh ../openwifi-hw/zc706_fmcs2/sdk/system_top_hw_platform_0/system.hdf u-boot-zc70x.elf 1412ee67178SXianjun Jiao(u-boot-zc70x.elf is included in the original Analog Devices Linux img) 1422ee67178SXianjun Jiao``` 1432ee67178SXianjun Jiao* 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. 144*9e8d5e4aSJiao Xianjun* 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): 1452ee67178SXianjun Jiao 1462ee67178SXianjun Jiao``` 1472ee67178SXianjun Jiaoexport SDCARD_DIR=sdcard_mount_point 1482ee67178SXianjun Jiaocp $OPENWIFI_DIR/kernel_boot/devicetree.dtb $SDCARD_DIR/BOOT 1492ee67178SXianjun Jiaocp $OPENWIFI_DIR/kernel_boot/output_boot_bin/BOOT.BIN $SDCARD_DIR/BOOT 1502ee67178SXianjun Jiaocp $OPENWIFI_DIR/adi-linux/arch/arm/boot/uImage $SDCARD_DIR/BOOT 1512ee67178SXianjun Jiaocd $SDCARD_DIR/BOOT 1522ee67178SXianjun Jiaosync 1532ee67178SXianjun Jiao 1542ee67178SXianjun Jiaosudo mkdir $SDCARD_DIR/rootfs/root/openwifi 1552ee67178SXianjun Jiaosudo find $OPENWIFI_DIR/driver -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/root/openwifi/ \; 1562ee67178SXianjun Jiaosudo cp $OPENWIFI_DIR/user_space/* $SDCARD_DIR/rootfs/root/openwifi/ 1572ee67178SXianjun Jiao 1582ee67178SXianjun Jiaosudo mkdir $SDCARD_DIR/rootfs/lib/modules 1592ee67178SXianjun Jiaosudo mkdir $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c 1602ee67178SXianjun Jiaosudo find $OPENWIFI_DIR/adi-linux -name \*.ko -exec cp {} $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c/ \; 1612ee67178SXianjun Jiaosudo rm $SDCARD_DIR/rootfs/lib/modules/4.14.0-g4220d5d24c6c/{axidmatest.ko,xilinx_dma.ko,adi_axi_hdmi.ko,ad9361_drv.ko} -f 1622ee67178SXianjun Jiao 1632ee67178SXianjun Jiaosudo rm $SDCARD_DIR/rootfs/etc/udev/rules.d/70-persistent-net.rules 1642ee67178SXianjun Jiaosudo cp $OPENWIFI_DIR/kernel_boot/70-persistent-net.rules $SDCARD_DIR/rootfs/etc/udev/rules.d/ 1652ee67178SXianjun Jiao(Above rule will auto-rename wlan0 to sdr0 which is the openwifi NIC name) 1662ee67178SXianjun Jiaocd $SDCARD_DIR/rootfs 1672ee67178SXianjun Jiaosync 1682ee67178SXianjun Jiao``` 1692ee67178SXianjun Jiao**Run Linux and do some post-config:** 1702ee67178SXianjun Jiao 1712ee67178SXianjun Jiao* 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: 1722ee67178SXianjun Jiao 1732ee67178SXianjun Jiao``` 1742ee67178SXianjun Jiaoln -s /lib/modules/4.14.0-g4220d5d24c6c /lib/modules/4.14.0-g4220d5d 1752ee67178SXianjun Jiao(in case some Linux use short hash) 1762ee67178SXianjun Jiaodepmod 1772ee67178SXianjun Jiao(Ignore the error messages) 1782ee67178SXianjun Jiaomodprobe mac80211 1792ee67178SXianjun Jiaocd openwifi 1802ee67178SXianjun Jiao./wgd.sh 1812ee67178SXianjun Jiao(Wait for the completion) 1822ee67178SXianjun Jiaoifconfig 1832ee67178SXianjun Jiao(You should see sdr0 interface) 1842ee67178SXianjun Jiaoiwlist sdr0 scan 1852ee67178SXianjun Jiao(You should see the Wi-Fi scan results) 1862ee67178SXianjun Jiao``` 1872ee67178SXianjun Jiao* Config ssh server and ethernet IP address of the board. In the PC serial console: 1882ee67178SXianjun Jiao 1892ee67178SXianjun Jiao``` 1902ee67178SXianjun Jiaopasswd 1912ee67178SXianjun Jiao(ssh server needs a password, such as "openwifi") 1922ee67178SXianjun JiaoAdd "UseDNS no" to /etc/ssh/sshd_config, otherwise ssh login takes too long time 1932ee67178SXianjun JiaoSet static IP to board (If you have DHCP server on PC, you can skip this step) 1942ee67178SXianjun JiaoAdd following content to /etc/network/interfaces 1952ee67178SXianjun Jiao auto lo eth0 1962ee67178SXianjun Jiao iface lo inet loopback 1972ee67178SXianjun Jiao iface eth0 inet static 1982ee67178SXianjun Jiao address 192.168.10.122 1992ee67178SXianjun Jiao netmask 255.255.255.0 2002ee67178SXianjun JiaoAdd following content to /etc/resolv.conf 2012ee67178SXianjun Jiao nameserver 8.8.8.8 2022ee67178SXianjun Jiao nameserver 4.4.4.4 2032ee67178SXianjun Jiao 2042ee67178SXianjun JiaoDisable update (long time hang) on boot or ssh session: 2052ee67178SXianjun Jiao sudo chmod -x /etc/update-motd.d/90-updates-available 2062ee67178SXianjun Jiao sudo chmod -x /etc/update-motd.d/91-release-upgrade 2072ee67178SXianjun Jiao 208*9e8d5e4aSJiao Xianjunreboot the board, and set proper IP (192.168.10.1) of the connected PC, then from the PC: 2092ee67178SXianjun Jiaossh [email protected] 2102ee67178SXianjun Jiao(password: openwifi) 2112ee67178SXianjun Jiao``` 212*9e8d5e4aSJiao Xianjun* Make on board file update easier: 213*9e8d5e4aSJiao Xianjun * 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: 214*9e8d5e4aSJiao Xianjun 215*9e8d5e4aSJiao Xianjun mount /dev/mmcblk0p1 /sdcard 216*9e8d5e4aSJiao Xianjun (Create /sdcard directory firstly if it doesn't exist) 217*9e8d5e4aSJiao Xianjun cp file /sdcard 218*9e8d5e4aSJiao Xianjun cd /sdcard 219*9e8d5e4aSJiao Xianjun sync 220*9e8d5e4aSJiao Xianjun cd / 221*9e8d5e4aSJiao Xianjun umount /sdcard 222*9e8d5e4aSJiao Xianjun (Remember to power cycle the board) 223*9e8d5e4aSJiao Xianjun * 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: 224*9e8d5e4aSJiao Xianjun 225*9e8d5e4aSJiao Xianjun ./sdcard_boot_update.sh 226*9e8d5e4aSJiao Xianjun (Above command downloads uImage, BOOT.BIN and devicetree.dtb, then copy them into boot partition. Remember to power cycle) 227*9e8d5e4aSJiao Xianjun ./wgd.sh remote 228*9e8d5e4aSJiao Xianjun (Above command downloads driver files, and brings up sdr0) 229*9e8d5e4aSJiao Xianjun 2302ee67178SXianjun Jiao**Compile user_space/sdrctl_src on the board** ("On the board" means that you login to the board via ssh) 2312ee67178SXianjun Jiao 2322ee67178SXianjun Jiao``` 2332ee67178SXianjun Jiaosudo apt-get install libnl-3-dev 2342ee67178SXianjun Jiaosudo apt-get install libnl-genl-3-dev 2352ee67178SXianjun Jiao(or find out .deb files by above commands and copy .deb to the board, if you do not have internet) 2362ee67178SXianjun Jiao 2372ee67178SXianjun Jiaocopy user_space/sdrctl_src to the board, then on the board: 2382ee67178SXianjun Jiaocd sdrctl_src 2392ee67178SXianjun Jiaochmod +x version.sh 2402ee67178SXianjun Jiaomake 2412ee67178SXianjun Jiao``` 2422ee67178SXianjun Jiao**Internet config** 2432ee67178SXianjun Jiao 2442ee67178SXianjun Jiao* Topology: client -- (sdr0)|zc706|(eth0) -- (***ethX***)|PC|(***ethY***) -- internet 2452ee67178SXianjun Jiao* Enable IPv4 IP forwarding on both zc706 and PC 2462ee67178SXianjun Jiao* On PC. After this your board should have internet via NAT through your PC. 2472ee67178SXianjun Jiao 2482ee67178SXianjun Jiao``` 2492ee67178SXianjun Jiaosudo iptables -t nat -A POSTROUTING -o ethY -j MASQUERADE 2502ee67178SXianjun Jiao``` 2512ee67178SXianjun Jiao* On board: Install dhcp server preparing for serving your openwifi clients via hostapd. 2522ee67178SXianjun Jiao 2532ee67178SXianjun Jiao``` 2542ee67178SXianjun Jiaosudo apt-get install isc-dhcp-server 2552ee67178SXianjun Jiaosudo apt-get install Haveged 2562ee67178SXianjun Jiao``` 2572ee67178SXianjun Jiao* Put user_space/dhcpd.conf into (overwrite) /etc/dhcp/dhcpd.conf on board. 2582ee67178SXianjun Jiao 2592ee67178SXianjun Jiao* On board: 2602ee67178SXianjun Jiao 2612ee67178SXianjun Jiao``` 2622ee67178SXianjun Jiaocd openwifi 2632ee67178SXianjun Jiaoservice network-manager stop 2642ee67178SXianjun Jiao./wgd.sh 2652ee67178SXianjun Jiaoifconfig sdr0 up 2662ee67178SXianjun Jiaoifconfig sdr0 192.168.13.1 2672ee67178SXianjun Jiaoroute add default gw 192.168.10.1 2682ee67178SXianjun Jiaoservice isc-dhcp-server restart 2692ee67178SXianjun Jiaohostapd hostapd-openwifi.conf 2702ee67178SXianjun Jiao``` 2712ee67178SXianjun Jiao* On PC: 2722ee67178SXianjun Jiao 2732ee67178SXianjun Jiao``` 2742ee67178SXianjun Jiaosudo ip route add 192.168.13.0/24 via 192.168.10.122 dev ethX 2752ee67178SXianjun Jiao``` 2762ee67178SXianjun Jiao* Now you can connect openwifi hotspot from your phone/laptop and access internet. 277