summaryrefslogtreecommitdiffstats
path: root/src/connections/wireless
blob: a5b7ad20cb6ff4b97c4ef666a85ebf6aedf0f49b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#! /bin/bash
. /usr/lib/network/network
. "$SUBR_DIR/8021x"
. "$SUBR_DIR/rfkill"

wireless_up() {

    PROFILE="$1"
    load_profile "$PROFILE"

    # Default settings
    SECURITY=${SECURITY:-none}
    WPA_DRIVER=${WPA_DRIVER:-nl80211,wext}

    enable_rf $INTERFACE $RFKILL $RFKILL_NAME || return 1

    # Check if interface exists
    is_interface "$INTERFACE" || { report_fail "interface $INTERFACE does not exist"; return 1; }

    # Kill any lingering wpa_supplicants.
    report_debug wireless_up stop_wpa "$INTERFACE"
    stop_wpa "$INTERFACE"

    # Start wpa_supplicant
    WPA_CTRL_PATH=/run/wpa_supplicant
    if [[ "$SECURITY" = "wpa-config" ]]; then
        WPA_CONF="${WPA_CONF:-/etc/wpa_supplicant.conf}"
        # Use defined control path (FS#24949)
        if grep "^ *ctrl_interface=" "$WPA_CONF" &>/dev/null; then
            WPA_CTRL_PATH=$(grep -m 1 "^ *ctrl_interface=" "$WPA_CONF" | tail -n 1 | cut -d= -f 2- | sed -r 's/DIR=(.*) +GROUP=.*/\1/')
        fi
    else
        WPA_CONF=$(make_wpa_config_file $INTERFACE)
    fi
    report_debug wireless_up start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"
    if ! start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"; then
        report_fail "wpa_supplicant did not start, possible configuration error"
        return 1
    fi

    # Scan for network's existence first
    if checkyesno "${SCAN:-no}"; then
        report_debug wireless_up scanning
        local OLDESSID="$ESSID"
        if [[ -n "$AP" ]]; then
            BSSID=$(wpa_find_ap "$INTERFACE" "$AP")
        else
            ESSID=$(wpa_find_essid "$INTERFACE" "$ESSID")
        fi
        if [[ $? -gt 0 ]]; then
            report_fail "Wireless network \"$OLDESSID\" not present."
            report_debug wireless_up stop_wpa "$INTERFACE"
            stop_wpa "$INTERFACE"
            return 1
        fi
    fi

    report_debug wireless_up stop_wpa "$INTERFACE"
    stop_wpa "$INTERFACE"

    # Build configuration file
    case "$SECURITY" in
        wpa-config)
            ;;
        none|wep|wpa|wpa-configsection)
            printf "%s\n" "network={" "$(make_wpa_config)" "}" >> "$WPA_CONF"
            report_debug wireless_up "Configuration generated at $WPA_CONF"
            ;;
        *)
            report_fail "Invalid SECURITY setting: $SECURITY"
            ;;
    esac

    # Bring interface up after starting wpa_supplicant
    # This is important since cards such as iwl3945 do not support
    # mode switching when they are already up.
    report_debug wireless_up ifup
    bring_interface up "$INTERFACE" || return 1

    report_debug wireless_up start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"
    if ! start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"; then
        report_fail "wpa_supplicant did not start, possible configuration error"
        return 1
    fi

    report_debug wireless_up wpa_check
    if ! wpa_check "$INTERFACE" "$TIMEOUT"; then
        report_fail "WPA Authentication/Association Failed"
        return 1
    fi

    if ! "$CONN_DIR/ethernet" up "$PROFILE"; then
        wireless_down "$PROFILE" YES
        return 1
    fi
}

# wireless_down PROFILE [ LEAVE ifconfig up? default no ]
wireless_down() {
    local PROFILE="$1"
    load_profile "$PROFILE"

    "$CONN_DIR/ethernet" down "$PROFILE"

    report_debug wireless_down stop_wpa "$INTERFACE"
    stop_wpa "$INTERFACE"
    rm -rf "$STATE_DIR/wpa.$INTERFACE"

    bring_interface down "$INTERFACE"

    # Handle wireless kill switches
    # Any reason why a hardware switch should be considered on interface down?
    if [[ "$RFKILL" == "soft" ]]; then
        set_rf_state "$INTERFACE" disabled $RFKILL_NAME || return 1
    fi
}

# Returns status of profile - is it still functional?
wireless_status() {
    load_profile "$1"
    if ! wpa_check_current_essid "$INTERFACE" "$ESSID"; then
        return 1
    elif ! ip link show dev "$INTERFACE" | fgrep -q "state UP"; then
        return 1
    fi

}

wireless_$1 "$2" "$3"
exit $?

# vim: ft=sh ts=4 et sw=4 tw=0: