Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / wifi / wifi_signal_noise_ @ d2161137

Historique | Voir | Annoter | Télécharger (3,19 ko)

1
#!/bin/sh
2
#
3
# Show current signal strength and noise for all connected peers of wifi devices.
4
# This plugin is suitable for wifi interfaces with a stable selection of peers
5
# (e.g. infrastructure).
6
# Author: Lars Kruse, devel@sumpfralle.de
7
# License: GPL v3 or later
8
#
9
# Requirements:
10
#  * "iwinfo" tool (alternatively: fall back to "iw" - with incomplete data)
11
#  * root privileges (for "iw" and "iwinfo")
12
#
13
# Magic markers
14
#%# capabilities=autoconf suggest
15
#%# family=auto
16

    
17

    
18
set -eu
19

    
20

    
21
# prefer "iwinfo" for information retrieval, if it is available
22
if which iwinfo >/dev/null; then
23
	# "iwinfo" has a stable output format but is only available on openwrt
24
	get_wifi_interfaces() { iwinfo | grep "^[a-zA-Z]" | awk '{print $1}'; }
25
	# return MAC of peer and the signal strength
26
	get_wifi_peers() { iwinfo "$1" assoclist | grep "^[0-9a-fA-F]" | awk '{print $1,$2}'; }
27
	# the noise should be the same for all peers
28
	get_wifi_noise() { iwinfo "$1" info | sed -n 's/^.* Noise: \([0-9-]\+\).*/\1/p'; }
29
else
30
	# "iw" is available everywhere - but its output format is not recommended for non-humans
31
	get_wifi_interfaces() { iw dev | awk '{ if ($1 == "Interface") print $2; }'; }
32
	get_wifi_peers() { iw dev wlan0 station dump \
33
		| awk '{ if ($1 == "Station") mac=$2; if (($1 == "signal") && ($2 == "avg:")) print mac,$3}'; }
34
	# TODO: there seems to be no way to retrieve the noise level via "iw"
35
	get_wifi_noise() { echo; }
36
fi
37

    
38

    
39
clean_fieldname() {
40
	echo "$1" | sed 's/^\([^A-Za-z_]\)/_\1/; s/[^A-Za-z0-9_]/_/g'
41
}
42

    
43

    
44
get_ip_for_mac() {
45
	local ip
46
	ip=$(arp -n | grep -iw "$1$" | awk '{print $1}' | sort | head -1)
47
	[ -n "$ip" ] && echo "$ip" && return 0
48
	# no IP found - return MAC instead
49
	echo "$1"
50
}
51

    
52

    
53
get_wifi_device_from_suffix() {
54
	local suffix
55
	local real_dev
56
	# pick the part after the basename of the real file
57
	suffix=$(basename "$0" | sed "s/^$(basename "$(readlink "$0")")//")
58
	for real_dev in $(get_wifi_interfaces); do
59
		[ "$suffix" != "$(clean_fieldname "$real_dev")" ] || echo "$real_dev"
60
	done | head -1
61
}
62

    
63

    
64
ACTION="${1:-}"
65

    
66
case "$ACTION" in
67
	config)
68
		wifi=$(get_wifi_device_from_suffix)
69
		echo "graph_title Wireless signal quality - $wifi"
70
		echo "graph_args --upper-limit 0"
71
		echo "graph_vlabel Signal and noise [dBm]"
72
		echo "graph_category network"
73
		echo "graph_info This graph shows the signal and noise for all wifi peers"
74
		echo "noise.label Noise floor"
75
		echo "noise.draw LINE"
76
		# sub graphs for all peers
77
		get_wifi_peers "$wifi" | while read mac signal; do
78
			fieldname=$(clean_fieldname "peer_${mac}")
79
			peer=$(get_ip_for_mac "$mac")
80
			echo "signal_${fieldname}.label $peer"
81
			echo "signal_${fieldname}.draw LINE"
82
		done
83
		;;
84
	autoconf)
85
		[ -z "$(get_wifi_interfaces)" ] && echo "no (no wifi interfaces found)" && exit 1
86
		echo "yes"
87
		;;
88
	suggest)
89
		get_wifi_interfaces | while read ifname; do
90
			clean_fieldname "$ifname"
91
		done
92
		;;
93
	"")
94
		wifi=$(get_wifi_device_from_suffix)
95
		peer_data=$(get_wifi_peers "$wifi")
96
		echo "$peer_data" | while read mac signal; do
97
			# ignore empty datasets
98
			[ -z "$signal" ] && continue
99
			fieldname=$(clean_fieldname "peer_${mac}")
100
			echo "signal_${fieldname}.value $signal"
101
		done
102
		echo "noise.value $(get_wifi_noise "$wifi")"
103
		;;
104
	*)
105
		echo >&2 "Invalid action (valid: config)"
106
		echo >&2
107
		;;
108
esac