#!/bin/sh # Copyright AllSeen Alliance. All rights reserved. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # . /lib/config/uci.sh . /usr/share/libubox/jshn.sh DEBUG= ERROR_NONE=0 ERROR_UNREACHABLE=1 ERROR_PROTOCOL=2 ERROR_UNAUTHORIZED=3 ERROR_GENERAL=4 WPA_CLI() { local iface=$1;shift local opt case ${iface} in global) opt="-g /var/run/wpa_supplicant-${iface}" ;; *) opt="-p /var/run/wpa_supplicant-${iface} -i ${iface}";; esac if [ -n "${DEBUG}" ]; then echo wpa_cli ${opt} "$@" >&2 wpa_cli ${opt} "$@" || exit 2 return 0 fi wpa_cli ${opt} "$@" >/dev/null 2>&1 || exit 2 } wifi_connect() { local ssid=$(uci get alljoyn-onboarding.@onboarding[0].ssid) local encryption=$(uci get alljoyn-onboarding.@onboarding[0].encryption) local key=$(uci get alljoyn-onboarding.@onboarding[0].key) if [ "$encryption" = "wep" ]; then local getwepkey="uci get alljoyn-onboarding.@onboarding[0].key$key" uci set wireless.@wifi-iface[0].key$key="$($getwepkey)" fi uci set wireless.@wifi-iface[0].mode=sta uci set wireless.@wifi-iface[0].network=obswifi uci set wireless.@wifi-iface[0].ssid="$ssid" uci set wireless.@wifi-iface[0].key="$key" uci set wireless.@wifi-iface[0].encryption=$encryption uci delete wireless.@wifi-iface[0].hidden uci commit wireless wifi # when in station mode, set the scan_wifi cron job to run every hour /etc/init.d/cron stop sed -i '/\/usr\/sbin\/wifi_scan/d' /etc/crontabs/root echo '1 * * * * /usr/sbin/wifi_scan' >> /etc/crontabs/root /etc/init.d/cron start } wifi_softap() { local ssid=$(uci get alljoyn-onboarding.@onboarding[0].apssid) local encryption=$(uci get alljoyn-onboarding.@onboarding[0].apencryption) local key=$(uci get alljoyn-onboarding.@onboarding[0].apkey) local hidden=$(uci get alljoyn-onboarding.@onboarding[0].aphidden) uci set wireless.@wifi-iface[0].mode=ap uci set wireless.@wifi-iface[0].network=lan uci set wireless.@wifi-iface[0].ssid="$ssid" uci set wireless.@wifi-iface[0].key="$key" uci set wireless.@wifi-iface[0].encryption=$encryption uci set wireless.@wifi-iface[0].hidden=$hidden uci commit wireless wifi # when in soft ap mode, set the scan_wifi cron job to run every 15 minutes /etc/init.d/cron stop sed -i '/\/usr\/sbin\/wifi_scan/d' /etc/crontabs/root echo '*/15 * * * * /usr/sbin/wifi_scan' >> /etc/crontabs/root /etc/init.d/cron start } wifi_reset() { wifi } wifi_configure_commit() { uci set alljoyn-onboarding.@onboarding[0].ssid="$1" uci set alljoyn-onboarding.@onboarding[0].encryption="$2" if [ "$2" = "wep" ]; then uci set alljoyn-onboarding.@onboarding[0].key="$5" uci set alljoyn-onboarding.@onboarding[0].key$5="$4" else uci set alljoyn-onboarding.@onboarding[0].key="$3" fi uci commit alljoyn-onboarding } wifi_connect_status() { ifstatus=$(ifstatus obswifi) json_load "$ifstatus" json_get_var iface device local timeout=4 local result=$ERROR_UNREACHABLE local conn_state=0 if [ -z $iface ]; then echo "Device not defined for obswifi" >&2 set_error $ERROR_UNREACHABLE "Unreachable" return $result fi while [ ${timeout} -gt 0 ]; do sleep 1 ctrl_iface=$(grep ctrl_interface /var/run/wpa_supplicant-${iface}.conf | sed s/ctrl_interface=//) if [ -z "${ctrl_iface}" ]; then conn_state=$(wpa_cli -i ${iface} status 2>/dev/null | grep wpa_state | cut -d= -f2) else conn_state=$(wpa_cli -i ${iface} -p ${ctrl_iface} status 2>/dev/null | grep wpa_state | cut -d= -f2) fi echo ${conn_state} >&2 if [ "${conn_state}" = "COMPLETED" ]; then result=$ERROR_NONE set_error $ERROR_NONE "Validated" return $result elif [ "${conn_state}" = "SCANNING" ]; then result=$ERROR_UNREACHABLE set_error $ERROR_UNREACHABLE "Unreachable" elif [ "${conn_state}" = "4WAY_HANDSHAKE" ]; then set_error $ERROR_UNAUTHORIZED "Unauthorized - 4WAY_HANDSHAKE timeout" result=$ERROR_UNAUTHORIZED elif [ "${conn_state}" = "DISCONNECTED" ]; then set_error $ERROR_UNAUTHORIZED "Unauthorized - DISCONNECTED" result=$ERROR_UNAUTHORIZED else result=$ERROR_PROTOCOL set_error $ERROR_PROTOCOL "Unsupported protocol" echo "wpa_cli returned unknown status" >&2 fi timeout=$((--timeout)) done echo "Timeout --> unreachable" >&2 return $result } showhelp() { cat << EOF $0 -s -a [-p ] [-k key] [-i index] [ -t timeout ] [ -d ] Mandatory parameters: -s : Connect to SSID -a : Use authentication , where can be one of: "open": No authentication "wep": WEP authentication "psk": WPA authentication "psk2": WPA2 authentication Optional parameters: -p : (WEP or WPA only) Set the WEP (string) or WPA passphrase -k : (WEP only) Set the key (hex key only, either 5 or 13 bytes len) -i : (WEP only) Set the key index (1-4) -t : Set the connection timeout (in seconds) - default=4 -d : enable debug -h : print this help Return value: 0: Connection Success 1: Connection Failed 2: Error EOF } check_params() { local ssid=$1 local auth=$2 local psk=$3 local key=$4 local index=$5 if [ -z "${auth}" ] || [ -z "${ssid}" ]; then echo "Error:ssid or authentication not found" >&2 return 1 fi # Using passphrase and/or key and/or index in Open mode is inconsistent if [ "${auth}" = "open" ]; then if [ -n "${key}" -o -n "${index}" -o -n "${psk}" ]; then echo "Open mode can't be used with passphrase/key/index" >&2 return 1 fi fi # If wep is used, make sure we also got a key & its index if [ "${auth}" = "wep" ]; then if [ -z "${key}" ]; then echo "In WEP, please specify the key and optionally, the index" >&2 return 1 fi fi # Having a key and/or index with non-WEP encryption is inconsistent if [ "${auth}" != "wep" ]; then if [ -n "${key}" -o -n "${index}" ]; then echo "Index/Key can't be used with non-WEP authentication " >&2 return 1 fi fi # If wpa is used, make sure we also got a passphrase case "$auth" in *psk*) if [ -z "${psk}" ]; then echo "In WPA, please specify a passphrase" >&2 return 1 fi if [ $(expr length "${psk}") -lt 8 ]; then echo "In WPA, please specify a passphrase of size at least 8" >&2 return 1 fi if [ $(expr length "${psk}") -eq 64 ]; then local i=0 while [ $i -lt 64 ]; do char=${psk:$i:1} case "$char" in [a-fA-F0-9] );; * ) echo "In WPA, please specify an ASCII passphrase of size less than 64 or a Hex passphrase of size 64" >&2 return 1;; esac i=$((i+1)) done elif [ $(expr length "${psk}") -gt 64 ]; then echo "In WPA, please specify an ASCII passphrase of size less than 64 or a Hex passphrase of size 64" >&2 return 1 fi ;; *) esac return 0 } wifi_configure() { # Process arguments local ssid auth psk key index while [ -n "$1" ];do case "$1" in -s) ssid="$2"; shift;; -a) auth="$2"; shift if [ "${auth}" = "OPEN" ]; then auth="none" fi if [ "${auth}" = "WEP" ]; then auth="wep" fi case "$auth" in WPA2*) auth="psk2+tkip+ccmp" ;; WPA*) auth="psk+tkip+ccmp" ;; esac if [ "${auth}" = "WPS" ]; then auth="psk" fi [ ${auth} = "none" ] || [ ${auth} = "wep" ] || [ ${auth} = "psk+tkip+ccmp" ] || [ ${auth} = "psk2+tkip+ccmp" ] || { echo "Invalid authentication \"${auth}\"" >&2 echo "Valid authentication values are \"none\", \"wep\", \"psk+tkip+ccmp\", \"psk2+tkip+ccmp\"" >&2 showhelp exit 2; };; -p) psk="$2"; shift;; -k) key="$2"; shift;; -i) index="$2"; shift if [ ! ${index} -ge 1 ] && [ ! ${index} -le 4 ]; then echo "Invalid index \"${index}\"" >&2 echo "Valid index values are \"1\", \"2\", \"3\", \"4\"" >&2 showhelp exit 2 fi;; -t) timeout="$2"; shift;; -d) DEBUG=1;; -h) showhelp; exit 2;; *) echo "Invalid option: -${OPTARG}" >&2 showhelp exit 2 ;; esac shift done if [ "${auth}" = "wep" ]; then if [ -z "${index}" ]; then index=1 echo "Defaulting index to 1" >&2 fi fi # Perform sanity checks on the script arguments check_params "${ssid}" "${auth}" "${psk}" "${key}" "${index}" || { showhelp exit 2 } wifi_configure_commit "${ssid}" "${auth}" "${psk}" "${key}" "${index}" } set_error() { uci set -c /etc/alljoyn-onboarding alljoyn-onboarding-state.@onboarding[0].lasterrorcode=$1 uci set -c /etc/alljoyn-onboarding alljoyn-onboarding-state.@onboarding[0].lasterrormsg="$2" uci commit -c /etc/alljoyn-onboarding alljoyn-onboarding-state printf '%s\n%s' "$1" "$2" > /tmp/state/alljoyn-onboarding-lasterror }