#!/bin/sh

### This is an init-script to facilitate auto-configuration of WiFi (bcmndis)
### during OI system startup. It is possible that the driver can panic the OS,
### so it creates a lock-file to block the start method from running if it
### did not finish previously (i.e. panicked on initialization).
### Interface configuration can be taken from classic /etc/hostname.* files or
### from identically constructed /etc/wifilink.* files (a hack for this script,
### so that OS does not detect and configure these interfaces).
### PROVIDED AS IS, FREE FOR ANY USE, NO WARRANTIES (your system *can* panic)
### Copyright (C) 2013 by Jim Klimov

[ x"$NDISAPI" = x ] &&	NDISAPI=ndisapi
[ x"$NDIS" = x ] &&	NDIS=bcmndis
[ x"$WIFI_INTERFACE" = x ] && \
    WIFI_INTERFACE=bcmndis0
[ x"$WIFI_PROFILE" = x -a -s /etc/inet/wifi ] && \
    WIFI_PROFILE="`cat /etc/inet/wifi | ggrep -A1 'preference' | tail -1`" || \
    WIFI_PROFILE=""
[ x"$WIFI_PROFILE" = x ] && \
    WIFI_PROFILE="jimhome-wep"
[ x"$LOCKFILE" = x ] && LOCKFILE=/etc/.wifi-block

#[ x"$MODDIR_BASE" = x ] &&	MODDIR_BASE="/usr/kernel"
[ x"$MODDIR_BASE" = x ] &&	MODDIR_BASE="/kernel"
[ x"$MODDIR_MISC" = x ] &&	MODDIR_MISC="${MODDIR_BASE}/misc"
[ x"$MODDIR_DRV" = x ] &&	MODDIR_DRV="${MODDIR_BASE}/drv"

_ISADIR=""
case "`isainfo`" in
    *amd64*)	_ISADIR="amd64/";;
esac
[ x"$MODDIR_ISA" = x ] &&	MODDIR_ISA="${_ISADIR}"

status() {
	echo "===== Info about currently loaded NDIS modules:"
	modinfo | egrep "${NDISAPI}|${NDIS}"
	echo "=== Current interface datalink config (if any):"
	dladm show-wifi
	echo "=== Current interface IP config (if any):"
	ifconfig ${WIFI_INTERFACE}
}

unplumb() {
	echo "===== Trying to UNPLUMB Wifi interface ${WIFI_INTERFACE}"
	echo "=== This would allow to unload the NDIS modules for further tests"
	echo "=== Current interface IP config (if any):"

	ifconfig ${WIFI_INTERFACE} || true
	sleep 3
	wificonfig -i ${WIFI_INTERFACE} disconnect || true
	ifconfig ${WIFI_INTERFACE} down unplumb || true
	sleep 3
	ifconfig ${WIFI_INTERFACE} || true
}

plumb() {
	echo "===== Trying to PLUMB Wifi interface ${WIFI_INTERFACE} and set up IP"
	echo "=== The NDIS modules should already be loaded (see above)"
	ifconfig ${WIFI_INTERFACE} plumb
	wificonfig -i ${WIFI_INTERFACE} connect ${WIFI_PROFILE}
	CONFIGURED=no
	for F in \
	    /etc/hostname.${WIFI_INTERFACE} \
	    /etc/hostname.${WIFI_INTERFACE}\:* \
	    /etc/wifilink.${WIFI_INTERFACE} \
	    /etc/wifilink.${WIFI_INTERFACE}\:* \
	; do
	    if [ -f "$F" ]; then
		CONFIGURED=yes
		ALIAS="`echo "$F" | grep : | sed 's/^.*://'`"
		if [ -s "$F" ]; then
		    echo "=== Applying config file '$F': `cat "$F"`"
		    if [ x"$ALIAS" != x ]; then
			### TODO: might expand...
			ifconfig ${WIFI_INTERFACE} addif `cat "$F"` up
		    else
			cat "$F" | while read L; do
			    ifconfig ${WIFI_INTERFACE} $L
			done
		    fi
		fi
	    fi
	done
	if [ x"$CONFIGURED" = xno ]; then
	    echo "=== No config files, request IP config via DHCP..."
	    ifconfig ${WIFI_INTERFACE} up
	    ifconfig ${WIFI_INTERFACE} dhcp
	fi
	echo "=== Current interface IP config:"
	ifconfig ${WIFI_INTERFACE}
}

unload() {
	echo "===== Trying to MODUNLOAD ${NDIS} and ${NDISAPI} (if loaded)"
	if modinfo | grep "${NDIS}"; then \
	    modunload -i `modinfo | grep "${NDIS}" | awk '{print $1}'`; \
	else true; fi
	if modinfo | grep "${NDISAPI}"; then \
	    modunload -i `modinfo | grep "${NDISAPI}" | awk '{print $1}'`; \
	else true; fi
	echo "=== Currently loaded NDIS modules (should be none):"
	if modinfo | egrep "${NDISAPI}|${NDIS}"; then false; else true; fi
}

load() {
	echo "===== Trying to MODLOAD ${NDISAPI} and ${NDIS} (if not loaded)"
	if ! modload ${MODDIR_MISC}/${MODDIR_ISA}${NDISAPI} ; then \
	    date; sleep 2; dmesg | grep ${NDISAPI} | tail; date; exit 1; \
	else true; fi
	if ! modload ${MODDIR_DRV}/${MODDIR_ISA}${NDIS} ; then \
	    date; sleep 2; dmesg | grep ${NDIS} | tail; date; exit 1; \
	else true; fi
	echo "=== Currently loaded NDIS modules:"
	modinfo | egrep "${NDIS}|${NDISAPI}"
}

case "$1" in
    status|state|modinfo)	status ;;
    load|modload)	load ;;
    unload|modunload)	unplumb; unload ;;
    plumb)		load; plumb ;;
    unplumb)		unplumb ;;

    stop)	unplumb; unload ;;

    start)	if [ -f "$LOCKFILE" ]; then
		    echo "WARN: WiFi lock file '$LOCKFILE' exists, not starting WiFi" >&2
		    echo "`date`: WARN: WiFi lock file '$LOCKFILE' exists, not starting WiFi" > /dev/console
		    exit 1
		fi
		trap "rm -f '$LOCKFILE'" 0 1 2 3 15
		touch "$LOCKFILE"; sync
    		load
    		plumb
    		;;

    restart)
		"$0" stop
		echo ""
		sleep 3
		"$0" start
		;;

    *)	echo "Unknown params: $@"; exit 1 ;;
esac
