3de5b04a004a33c3c477109faad9e7838af72018
[openwrt.git] / package / hostap-driver / files / lib / wifi / hostap.sh
1 #!/bin/sh
2 append DRIVERS "prism2"
3
4 find_prism2_phy() {
5         local device="$1"
6
7         local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
8         config_get phy "$device" phy
9         [ -z "$phy" -a -n "$macaddr" ] && {
10                 cd /proc/net/hostap
11                 for phy in $(ls -d wlan* 2>&-); do
12                         [ "$macaddr" = "$(cat /sys/class/net/${phy}/address)" ] || continue
13                         config_set "$device" phy "$phy"
14                         break
15                 done
16                 config_get phy "$device" phy
17         }
18         [ -n "$phy" -a -d "/proc/net/hostap/$phy" ] || {
19                 echo "phy for wifi device $1 not found"
20                 return 1
21         }
22         [ -z "$macaddr" ] && {
23                 config_set "$device" macaddr "$(cat /sys/class/net/${phy}/address)"
24         }
25         return 0
26 }
27
28 scan_prism2() {
29         local device="$1"
30         local mainvif
31         local wds
32
33         [ ${device%[0-9]} = "wlan" ] && config_set "$device" phy "$device" || find_prism2_phy "$device" || {
34                 config_unset "$device" vifs
35                 return 0
36         }
37         config_get phy "$device" phy
38
39         config_get vifs "$device" vifs
40         local _c=0
41         for vif in $vifs; do
42                 config_get mode "$vif" mode
43                 case "$mode" in
44                         adhoc|sta|ap|monitor)
45                                 # Only one vif is allowed on AP, station, Ad-hoc or monitor mode
46                                 [ -z "$mainvif" ] && {
47                                         mainvif="$vif"
48                                         config_set "$vif" ifname "$phy"
49                                 }
50                         ;;
51                         wds)
52                                 config_get ssid "$vif" ssid
53                                 [ -z "$ssid" ] && continue
54                                 config_set "$vif" ifname "${phy}wds${_c}"
55                                 _c=$(($_c + 1))
56                                 addr="$ssid"
57                                 ${addr:+append wds "$vif"}
58                         ;;
59                         *) echo "$device($vif): Invalid mode, ignored."; continue;;
60                 esac
61         done
62         config_set "$device" vifs "${mainvif:+$mainvif }${wds:+$wds}"
63 }
64
65 disable_prism2() (
66         local device="$1"
67
68         find_prism2_phy "$device" || return 0
69         config_get phy "$device" phy
70
71         set_wifi_down "$device"
72
73         include /lib/network
74         while read line < /proc/net/hostap/${phy}/wds; do
75                 set $line
76                 [ -f "/var/run/wifi-${1}.pid" ] &&
77                         kill "$(cat "/var/run/wifi-${1}.pid")"
78                 ifconfig "$1" down
79                 unbridge "$1"
80                 iwpriv "$phy" wds_del "$2"
81         done
82         unbridge "$phy"
83         return 0
84 )
85
86 enable_prism2() {
87         local device="$1"
88
89         find_prism2_phy "$device" || return 0
90         config_get phy "$device" phy
91
92         config_get rxantenna "$device" rxantenna
93         config_get txantenna "$device" txantenna
94         config_get_bool diversity "$device" diversity
95         [ -n "$diversity" ] && {
96                 rxantenna="1"
97                 txantenna="1"
98         }
99         [ -n "$rxantenna" ] && iwpriv "$phy" antsel_rx "$rxantenna"
100         [ -n "$txantenna" ] && iwpriv "$phy" antsel_tx "$txantenna"
101
102         config_get channel "$device" channel
103         [ -n "$channel" ] && iwconfig "$phy" channel "$channel" >/dev/null 2>/dev/null
104
105         config_get txpower "$device" txpower
106         [ -n "$txpower" ] && iwconfig "$phy" txpower "${txpower%%.*}"
107
108         config_get vifs "$device" vifs
109         local first=1
110         for vif in $vifs; do
111                 config_get ifname "$vif" ifname
112                 config_get ssid "$vif" ssid
113                 config_get mode "$vif" mode
114
115                 [ "$mode" = "wds" ] || iwconfig "$phy" essid -- "$ssid"
116
117                 case "$mode" in
118                         sta)
119                                 iwconfig "$phy" mode managed
120                                 config_get addr "$device" bssid
121                                 [ -z "$addr" ] || { 
122                                         iwconfig "$phy" ap "$addr"
123                                 }
124                         ;;
125                         ap) iwconfig "$phy" mode master;;
126                         wds) iwpriv "$phy" wds_add "$ssid";;
127                         adhoc) iwconfig "$phy" mode ad-hoc;;
128                         *) iwconfig "$phy" mode "$mode";;
129                 esac
130
131                 [ "$first" = 1 ] && {
132                         config_get rate "$vif" rate
133                         [ -n "$rate" ] && iwconfig "$phy" rate "${rate%%.*}"
134
135                         config_get_bool hidden "$vif" hidden 0
136                         iwpriv "$phy" enh_sec "$hidden"
137
138                         config_get frag "$vif" frag
139                         [ -n "$frag" ] && iwconfig "$phy" frag "${frag%%.*}"
140
141                         config_get rts "$vif" rts
142                         [ -n "$rts" ] && iwconfig "$phy" rts "${rts%%.*}"
143
144                         config_get maclist "$vif" maclist
145                         [ -n "$maclist" ] && {
146                                 # flush MAC list
147                                 iwpriv "$phy" maccmd 3
148                                 for mac in $maclist; do
149                                         iwpriv "$phy" addmac "$mac"
150                                 done
151                         }
152                         config_get macpolicy "$vif" macpolicy
153                         case "$macpolicy" in
154                                 allow)
155                                         iwpriv "$phy" maccmd 2
156                                 ;;
157                                 deny)
158                                         iwpriv "$phy" maccmd 1
159                                 ;;
160                                 *)
161                                         # default deny policy if mac list exists
162                                         [ -n "$maclist" ] && iwpriv "$phy" maccmd 1
163                                 ;;
164                         esac
165                         # kick all stations if we have policy explicitly set
166                         [ -n "$macpolicy" ] && iwpriv "$phy" maccmd 4
167                 }
168
169                 config_get enc "$vif" encryption
170                 case "$enc" in
171                         WEP|wep)
172                                 for idx in 1 2 3 4; do
173                                         config_get key "$vif" "key${idx}"
174                                         iwconfig "$ifname" enc "[$idx]" "${key:-off}"
175                                 done
176                                 config_get key "$vif" key
177                                 key="${key:-1}"
178                                 case "$key" in
179                                         [1234]) iwconfig "$ifname" enc "[$key]";;
180                                         *) iwconfig "$ifname" enc "$key";;
181                                 esac
182                         ;;
183                         psk*|wpa*)
184                                 start_hostapd=1
185                                 config_get key "$vif" key
186                         ;;
187                 esac
188
189                 local net_cfg bridge
190                 net_cfg="$(find_net_config "$vif")"
191                 [ -z "$net_cfg" ] || {
192                         bridge="$(bridge_interface "$net_cfg")"
193                         config_set "$vif" bridge "$bridge"
194                         start_net "$ifname" "$net_cfg"
195                 }
196                 set_wifi_up "$vif" "$ifname"
197
198                 case "$mode" in
199                         ap)
200                                 if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then
201                                         hostapd_setup_vif "$vif" hostap || {
202                                                 echo "enable_prism2($device): Failed to set up hostapd for interface $ifname" >&2
203                                                 # make sure this wifi interface won't accidentally stay open without encryption
204                                                 ifconfig "$ifname" down
205                                                 continue
206                                         }
207                                 fi
208                         ;;
209                         wds|sta)
210                                 if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
211                                         wpa_supplicant_setup_vif "$vif" hostap || {
212                                                 echo "enable_prism2($device): Failed to set up wpa_supplicant for interface $ifname" >&2
213                                                 ifconfig "$ifname" down
214                                                 continue
215                                         }
216                                 fi
217                         ;;
218                 esac
219                 first=0
220         done
221
222 }
223
224 check_prism2_device() {
225         [ ${1%[0-9]} = "wlan" ] && config_set "$1" phy "$1"
226         config_get phy "$1" phy
227         [ -z "$phy" ] && {
228                 find_prism2_phy "$1" >/dev/null || return 0
229                 config_get phy "$1" phy
230         }
231         [ "$phy" = "$dev" ] && found=1
232 }
233
234 detect_prism2() {
235         devidx=0
236         config_load wireless
237         while :; do
238                 config_get type "radio$devidx" type
239                 [ -n "$type" ] || break
240                 devidx=$(($devidx + 1))
241         done
242         cd /proc/net/hostap
243         [ -d wlan* ] || return
244         for dev in $(ls -d wlan* 2>&-); do
245                 found=0
246                 config_foreach check_prism2_device wifi-device
247                 [ "$found" -gt 0 ] && continue
248                 cat <<EOF
249
250 config wifi-device radio$devidx
251         option type     prism2
252         option channel  11
253         option macaddr  $(cat /sys/class/net/${dev}/address)
254
255         # REMOVE THIS LINE TO ENABLE WIFI:
256         option disabled 1
257
258 config wifi-iface
259         option device   radio$devidx
260         option network  lan
261         option mode     ap
262         option ssid     OpenWrt
263         option encryption none
264
265 EOF
266         devidx=$(($devidx + 1))
267         done
268 }