blob: 46132316c7554a208c2aef5f8605ba845ca4efad [file] [log] [blame]
#!/bin/sh
band=5
ssid=$(serial)_TestWifi
crypto=WPA2_PSK_AES
channel=auto
# use $WIFI_PSK from the environment if given.
# You shouldn't pass passwords as command-line options because they show up
# in 'ps' even to users other than you.
psk=${WIFI_PSK-1234567890}
. /etc/utils.sh
log() {
echo "$@" >&2
}
die() {
log "Fatal:" "$@"
exit 99
}
bin=$(basename "$0")
USAGE="
Usage: $bin set [options...]
-b <band> Wifi band to use (5 GHz or 2.4 GHz, default=$band)
-c <channel> Channel to use (default=$channel)
-s <ssid> SSID to use (default=$ssid)
-e <encryption> Encryption type to use (WPA_PSK_AES,
WPA2_PSK_AES, WPA_PSK_TKIP, WPA2_PSK_TKIP,
WEP, or NONE) (default=$crypto)
"
usage() {
echo "$USAGE"
exit 1
}
WL() {
log "wl" "$@"
wl "$@" || die "wl $*: failed"
}
IWCONFIG() {
log "iwconfig" "$@"
iwconfig "$@" || die "iwconfig $*: failed"
}
# Only 'set' command exists right now, but use it for extensibility later
cmd=$1
if [ "$cmd" != "set" ]; then
usage
fi
shift
while getopts "b:s:e:c:" opt
do
case $opt in
b) band=$OPTARG ;;
c) channel=$OPTARG ;;
s) ssid=$OPTARG ;;
e) crypto=$OPTARG ;;
*) usage ;;
esac
done
if runnable wl; then
log "Configuring broadcom wifi."
WL radio on
WL down
WL ssid ""
[ "$channel" = "auto" ] || band=auto
case $band in
5) WL band a ;;
2.4) WL band b ;;
auto) WL band auto ;;
*) die "invalid band '$band'" ;;
esac
WL ap 0
WL up
if [ "$channel" = "auto" ]; then
# We can only run autochannel when ap=0, but setting ap=1 later will
# wipe the value. So we have to capture the autochannel setting, then
# set it later. 'wl autochannel 2' is thus useless.
WL autochannel 1
sleep 3 # enough time to scan all the 2.4 or 5 GHz channels at 100ms each
channel=$(WL autochannel | ( read chan junk; echo "$chan"; ))
fi
WL ap 1
WL chanspec "$channel"
WL auth 0
WL infra 1
case $crypto in
*_AES) WL wsec 4 ;;
*_TKIP) WL wsec 2 ;;
WEP) WL wsec 1 ;;
NONE) WL wsec 0 ;;
*) die "invalid crypto '$crypto'" ;;
esac
WL sup_wpa 1
case $crypto in
WPA_*) WL wpa_auth 4 ;;
WPA2_*) WL wpa_auth 128 ;;
WEP|NONE) WL wpa_auth 0 ;;
*) die "invalid crypto '$crypto'" ;;
esac
WL up
case $crypto in
*_PSK_*)
# WPA keys must be added *before* setting the SSID
WL set_pmk "$psk"
WL ssid "$ssid"
;;
WEP)
# WEP keys must be added *after* setting the SSID
WL ssid "$ssid"
WL addwep 0 "$psk"
;;
NONE)
WL ssid "$ssid"
;;
*)
die "invalid crypto '$crypto'"
;;
esac
elif runnable iwconfig; then
log "Configuring atheros wifi."
ifc=$(
ifcname=
iwlist channel 2>/dev/null |
while read word channum colon freq junk; do
case $word in
Channel)
startswith "$freq" "$band" || continue
if [ "$channel" = "auto" ] ||
[ "$channum" = "$channel" -o "$channum" = "0$channel" ]; then
echo "$ifcname"
break
fi
;;
*)
ifcname=$word
;;
esac
done
)
[ -n "$ifc" ] || die "no wifi interface for band='$band' channel='$channel'"
log "Using wifi interface: '$ifc'"
IWC() {
IWCONFIG "$ifc" "$@"
}
for mode in 11ACVHT80 11ACVHT40 11NGHT40 11ACVHT20 11NGHT20; do
if iwpriv "$ifc" mode "$mode" 2>/dev/null; then
log "Mode for $ifc is $mode"
break
fi
done
IWC essid ""
IWC mode master
IWC channel "$channel" # may be "auto"
case $crypto in
WPA_*) auth_algs=1; wpa=1 ;;
WPA2_*) auth_algs=1; wpa=2 ;;
WEP) auth_algs=3; wpa=0 ;;
NONE) auth_algs=1; wpa=0 ;;
*) die "invalid crypto protocol in '$crypto'" ;;
esac
case $crypto in
*_AES) wpa_pairwise=CCMP ;;
*_TKIP) wpa_pairwise=TKIP ;;
WEP|NONE) wpa_pairwise=CCMP ;;
*) die "invalid crypto alg in '$crypto'" ;;
esac
atomic /tmp/hostapd.conf.${band}g "
interface=$ifc
ssid=$ssid
auth_algs=$auth_algs
wpa=$wpa
wpa_passphrase=$psk
wpa_key_mgmt=WPA-PSK
wpa_pairwise=$wpa_pairwise
"
case $crypto in
WPA2_*|WPA_*|WEP|NONE)
pidfile=/tmp/hostapd.pid.${band}g
babysit 60 startpid /tmp/hostapd.pid.${band}g \
hostapd -dK /tmp/hostapd.conf.${band}g \
2>&1 | logos hostapd-${band}g &
;;
*)
die "invalid crypto '$crypto'"
;;
esac
IWC essid -- "$ssid"
else
die "No wifi runtime found."
fi