#!/bin/sh

# Source function library
. /etc/init.d/functions

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DESC=WiFi

IFACE_STA=wlan0
DAEMON_STA=/usr/sbin/wpa_supplicant
PIDFILE_STA=/var/run/wpa_supplicant/${IFACE_STA}.pid

IFACE_AP=wlan1
DAEMON_AP=/usr/sbin/hostapd
PIDFILE_AP=/var/run/hostapd.${IFACE_AP}.pid

DAEMON_DHCP=udhcpc
PIDFILE_DHCP=/var/run/udhcpc.${IFACE_STA}.pid

ALL_24CHAN="2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467 2472"
NOOLAP_24CHAN="2412 2437 2462"
ALL_58CHAN="5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 5540 5560 5580 5600 5620 5640 5660 5680 5700"
NOOLAP_58CHAN="5180 5220 5260 5300 5500 5540 5580 5620 5660"
NOOLAP_40_58CHAN="5180 5260 5500 5580 5660"

I2C=$(ls -d  /sys/bus/i2c/drivers/nau8810/*1a |cut -d/ -f7 |cut -d- -f1)

if [ -e /etc/default/wifi ];then
	source /etc/default/wifi
fi;

set -e

scan_freq(){
	iw ${1} scan |grep -Po '(signal|freq):\K.*' | paste -d ' ' - - > /tmp/wifi.scan
	for freq in ${NOOLAP_24CHAN} ${NOOLAP_40_58CHAN};do
		(echo "-99.99 ${freq}";
		awk -v freq=${freq} '$1 == freq {printf "%s %s\n",$2,$1}' /tmp/wifi.scan) |sort -n |tail -1
	done;
	rm /tmp/wifi.scan
}

get_chan(){
	freq=$(scan_freq ${1} |sort -nr |tail -1 |awk '{printf $2}')
	case ${freq} in
		2412)chan=1;;
		2417)chan=2;;
		2422)chan=3;;
		2427)chan=4;;
		2432)chan=5;;
		2437)chan=6;;
		2442)chan=7;;
		2447)chan=9;;
		2452)chan=9;;
		2457)chan=10;;
		2462)chan=11;;
		2467)chan=12;;
		2472)chan=13;;
		5180)chan=36;;
		5200)chan=40;;
		5220)chan=44;;
		5240)chan=48;;
		5260)chan=52;;
		5280)chan=56;;
		5300)chan=60;;
		5320)chan=64;;
		5500)chan=100;;
		5520)chan=104;;
		5540)chan=108;;
		5560)chan=112;;
		5580)chan=116;;
		5600)chan=120;;
		5620)chan=124;;
		5640)chan=128;;
		5660)chan=132;;
		5680)chan=136;;
		5700)chan=140;;
	esac
	echo ${chan}
}

get_i2c() {
	if i2cdetect -a -r -y ${I2C} 0x${1} 0x${1} |tail -8 |cut -c5- |grep ${1} > /dev/null 2>&1;then
		return 0;
	else
		return 1;
	fi;
}

hostapd_conf(){
	chan=$(get_chan ${1})
	if [ ${chan} -lt 15 ];then
		mode="g"
		width="HT20"
	else
		mode="a"
		width="HT40+"
	fi;

	if [ ! "${SSID}" ] && [ "${WIFI_MODE}" == "DEF" ];then
		SSID=$(awk -F: '{printf "comb-ns-%s%s%s%s",$3,$4,$5,$6}' /sys/class/net/${1}/address)
		if get_i2c 50;then
			PPHRASE=$(echo -n 0010;for mac in a b c d e f;do MV=$(i2cget -y ${I2C} 0x50 0xf${mac});echo -n ${MV:2};done)
		else
			PPHRASE="password"
		fi;
		PSK=$(wpa_passphrase ${SSID} ${PPHRASE} |awk -F= '/\tpsk=/ {printf "%s\n",$2}')
		/usr/bin/avahi-set-host-name ${SSID} |true
		/bin/hostname ${SSID}
	elif [ ! "${SSID}" ];then
		return 1;
	fi;

	cat<<__EOF_HOSTAPD__
interface=${1}
hw_mode=${mode}
country_code=ZA
ieee80211h=1
ieee80211d=1
ieee80211n=1
ht_capab=[${width}][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40][MAX-AMSDU-3839]
ieee80211ac=1
wmm_enabled=1
channel=${chan}

auth_algs=1
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
rsn_pairwise=TKIP CCMP

wpa_psk=${PSK}
ssid=${SSID}
__EOF_HOSTAPD__
}


supplicant_config() {
  cat<<__EOF__
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1
country=ZA

network={
	ssid="${1}"
        psk=${2}
}
__EOF__
}


setup_ap() {
	if [ ! "${1}" ];then
		/sbin/ip link set nomaster dev ${IFACE_AP}
		/sbin/ip addr flush dev ${IFACE_AP}
		/sbin/ip addr add ${IP}/${SN} dev ${IFACE_AP}
	elif [ ! -d /sys/class/net/$IFACE/brif/${IFACE_AP} ];then
		/sbin/ip addr flush dev ${IFACE_AP}
		/sbin/ip link set dev ${IFACE_AP} master ${1}
	fi
}

case $1 in
  start)
	echo -n "Starting ${DESC}: "
	if [ ! -e /sys/class/net/${IFACE_STA} ];then
		echo  "No WiFi support"
		exit 0
	fi;
	if [ -e /etc/wpa_supplicant.conf ] && [ "${WIFI_MODE}" == "STA" ];then
		/sbin/ip link set dev ${IFACE_AP} down
		/sbin/ip link set dev ${IFACE_STA} up
		start-stop-daemon --start -p ${PIDFILE_STA} ${DAEMON_STA} -- -B -P ${PIDFILE_STA} -D nl80211 -i ${IFACE_STA}  -c /etc/wpa_supplicant.conf
		start-stop-daemon --start -p ${PIDFILE_DHCP} ${DAEMON_DHCP} -- -R -b -p ${PIDFILE_DHCP} -i ${IFACE_STA}
	elif [ ! -e /etc/wpa_supplicant.conf ] && [ "${WIFI_MODE}" == "STA" ] &&  [ "${SSID}" ] &&  [ "${PSK}" ];then
		/sbin/ip link set dev ${IFACE_AP} down
		/sbin/ip link set dev ${IFACE_STA} up
		supplicant_config ${SSID} ${PSK} > /tmp/wpa_supplicant.conf
		start-stop-daemon --start -p ${PIDFILE_STA} ${DAEMON_STA} -- -B -P ${PIDFILE_STA} -D nl80211 -i ${IFACE_STA}  -c /tmp/wpa_supplicant.conf
		start-stop-daemon --start -p ${PIDFILE_DHCP} ${DAEMON_DHCP} -- -R -b -p ${PIDFILE_DHCP} -i ${IFACE_STA}
	elif [ -e /etc/hostapd.conf ] && [ "${WIFI_MODE}" != "OFF" ];then
		/sbin/ip link set dev ${IFACE_STA} down
		/sbin/ip link set dev ${IFACE_AP} up
		setup_ap ${WIFI_AP_BRIDGE}
		start-stop-daemon --start -p ${PIDFILE_AP} ${DAEMON_AP} -- -P ${PIDFILE_AP} -B /etc/hostapd.conf
		/sbin/ip route add 169.254.0.0/16 dev ${IFACE_AP} scope link metric 1100
	elif [ ! -e /etc/hostapd.conf ] && [ "${WIFI_MODE}" ] && [ "${WIFI_MODE}" != "OFF" ];then
		setup_ap  ${WIFI_AP_BRIDGE}
		/sbin/ip link set dev ${IFACE_STA} down
		/sbin/ip link set dev ${IFACE_AP} up
		hostapd_conf ${IFACE_AP} ${SSID} ${PSK} > /tmp/hostapd.conf
		start-stop-daemon --start -p ${PIDFILE_AP} ${DAEMON_AP} -- -P ${PIDFILE_AP} -B /tmp/hostapd.conf
		/sbin/ip route add 169.254.0.0/16 dev ${IFACE_AP} scope link metric 1100
	fi;
  ;;
  stop)
	echo -n "Stopping {$DESC}: "
	if [ -e ${PIDFILE_STA} ];then
		/sbin/ip addr flush dev ${IFACE_STA}
		start-stop-daemon --stop -p ${PIDFILE_STA} ${DAEMON_STA} || true
		/sbin/ip link set dev ${IFACE_STA} down
		if [ -e ${PIDFILE_STA} ];then
			rm ${PIDFILE_STA}
		fi;
	fi;
	if [ -e ${PIDFILE_AP} ];then
		/sbin/ip addr flush dev ${IFACE_AP}
		start-stop-daemon --stop -s SIGKILL -p ${PIDFILE_AP} ${DAEMON_AP} || true
		/sbin/ip link set dev ${IFACE_AP} down
		if [ -e ${PIDFILE_AP} ];then
			rm ${PIDFILE_AP}
		fi;
	fi;
	if [ -e ${PIDFILE_DHCP} ];then
		start-stop-daemon --stop -s SIGKILL -p ${PIDFILE_DHCP} ${DAEMON_DHCP} || true
		if [ -e ${PIDFILE_DHCP} ];then
			rm ${PIDFILE_DHCP}
		fi;
	fi;
  ;;
  restart|force-reload)
	$0 stop
	sleep 1
	$0 start
  ;;
  status)
	status ${DAEMON} || exit $?
   ;;
   *)
	N=/etc/init.d/wifi
	echo "Usage: $N {start|stop|restart|force-reload|status}" >&2
	exit 1
	;;
esac

exit 0
