Projet

Général

Profil

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

root / plugins / wifi / wireless_signal_noise_ @ c81c20ab

Historique | Voir | Annoter | Télécharger (4,05 ko)

1
#!/bin/sh
2

    
3
: << =cut
4

    
5
=head1 NAME
6

    
7
wireless_signal_noise_ - Show signal strength and noise for all connected peers of wifi interface
8

    
9
=head1 APPLICABLE SYSTEMS
10

    
11
This plugin is suitable for wifi interfaces with a stable selection of peers (e.g. infrastructure).
12
It is probably not useful for hotspot-like scenarios.
13

    
14
Information is parsed from the output of the tool "iwinfo" (OpenWrt) or "iw" (most systems,
15
incomplete information).
16

    
17

    
18
=head1 CONFIGURATION
19

    
20
Symlink this plugin with the name of the wifi interface added (e.g. "wlan0").
21

    
22
Root permissions are probably required for accessing "iw".
23

    
24
  [wireless_signal_noise_*]
25
  user root
26

    
27

    
28
=head1 VERSION
29

    
30
  1.1
31

    
32

    
33
=head1 AUTHOR
34

    
35
Lars Kruse <devel@sumpfralle.de>
36

    
37

    
38
=head1 LICENSE
39

    
40
GPLv3 or above
41

    
42

    
43
=head1 MAGIC MARKERS
44

    
45
  #%# family=auto
46
  #%# capabilities=autoconf suggest
47

    
48
=cut
49

    
50

    
51
set -eu
52

    
53

    
54
SCRIPT_PREFIX="wireless_signal_noise_"
55

    
56

    
57
# prefer "iwinfo" for information retrieval, if it is available
58
if which iwinfo >/dev/null; then
59
	# "iwinfo" has a stable output format but is only available on openwrt
60
	get_wifi_interfaces() { iwinfo | grep "^[a-zA-Z]" | awk '{print $1}'; }
61
	# return MAC of peer and the signal strength
62
	get_wifi_peers() { iwinfo "$1" assoclist | grep "^[0-9a-fA-F]" | awk '{print $1,$2}'; }
63
	# the noise should be the same for all peers
64
	get_wifi_noise() { iwinfo "$1" info | sed -n 's/^.* Noise: \([0-9-]\+\).*/\1/p'; }
65
else
66
	# "iw" is available everywhere - but its output format is not recommended for non-humans
67
	get_wifi_interfaces() { iw dev | awk '{ if ($1 == "Interface") print $2; }'; }
68
	get_wifi_peers() { iw dev wlan0 station dump \
69
		| awk '{ if ($1 == "Station") mac=$2; if (($1 == "signal") && ($2 == "avg:")) print mac,$3}'; }
70
	# TODO: there seems to be no way to retrieve the noise level via "iw"
71
	get_wifi_noise() { echo; }
72
fi
73
if which arp >/dev/null; then
74
	# openwrt does not provide 'arp' by default
75
	get_arp() { arp -n; }
76
else
77
	get_arp() { cat /proc/net/arp; }
78
fi
79

    
80

    
81
clean_fieldname() {
82
	echo "$1" | sed 's/^\([^A-Za-z_]\)/_\1/; s/[^A-Za-z0-9_]/_/g'
83
}
84

    
85

    
86
get_ip_for_mac() {
87
	local ip
88
	ip=$(get_arp | grep -iw "$1$" | awk '{print $1}' | sort | head -1)
89
	[ -n "$ip" ] && echo "$ip" && return 0
90
	# no IP found - return MAC instead
91
	echo "$1"
92
}
93

    
94

    
95
get_wifi_device_from_suffix() {
96
	local suffix
97
	local real_dev
98
	# pick the part after the basename of the real file
99
	suffix=$(basename "$0" | sed "s/^$SCRIPT_PREFIX//")
100
	for real_dev in $(get_wifi_interfaces); do
101
		[ "$suffix" != "$(clean_fieldname "$real_dev")" ] || echo "$real_dev"
102
	done | head -1
103
}
104

    
105

    
106
do_config() {
107
	local wifi
108
	wifi=$(get_wifi_device_from_suffix)
109
	[ -z "$wifi" ] && echo >&2 "Missing wifi: $wifi" && return 1
110
	echo "graph_title Wireless signal quality - $wifi"
111
	echo "graph_args --upper-limit 0"
112
	echo "graph_vlabel Signal and noise [dBm]"
113
	echo "graph_category network"
114
	echo "graph_info This graph shows the signal and noise for all wifi peers"
115
	echo "noise.label Noise floor"
116
	echo "noise.draw LINE"
117
	# sub graphs for all peers
118
	get_wifi_peers "$wifi" | while read -r mac signal; do
119
		fieldname=$(clean_fieldname "peer_${mac}")
120
		peer=$(get_ip_for_mac "$mac")
121
		echo "signal_${fieldname}.label $peer"
122
		echo "signal_${fieldname}.draw LINE"
123
	done
124
}
125

    
126

    
127
do_fetch() {
128
	local wifi
129
	local peer_data
130
	local noise
131
	wifi=$(get_wifi_device_from_suffix)
132
	[ -z "$wifi" ] && echo >&2 "Missing wifi: $wifi" && return 1
133
	peer_data=$(get_wifi_peers "$wifi")
134
	echo "$peer_data" | while read -r mac signal; do
135
		# ignore empty datasets
136
		[ -z "$signal" ] && continue
137
		fieldname=$(clean_fieldname "peer_${mac}")
138
		echo "signal_${fieldname}.value $signal"
139
	done
140
	noise=$(get_wifi_noise "$wifi")
141
	echo "noise.value ${noise:-U}"
142
}
143

    
144

    
145
ACTION="${1:-}"
146

    
147
case "$ACTION" in
148
	config)
149
		do_config || exit 1
150
		if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then do_fetch; fi
151
		;;
152
	autoconf)
153
		if [ -z "$(get_wifi_interfaces)" ]; then
154
			echo "no (no wifi interfaces found)"
155
		else
156
			echo "yes"
157
		fi
158
		;;
159
	suggest)
160
		get_wifi_interfaces | while read -r ifname; do
161
			clean_fieldname "$ifname"
162
		done
163
		;;
164
	"")
165
		do_fetch
166
		;;
167
	*)
168
		echo >&2 "Invalid action (valid: config / suggest / autoconf / <empty>)"
169
		echo >&2
170
		exit 2
171
		;;
172
esac