#!/bin/sh

: << =cut

=head1 NAME

wireless_channel_occupation_ - Monitor occupation of wireless channels


=head1 APPLICABLE SYSTEMS

All systems with at least one wireless interface and the the tool "iw".

The wifi channel occupation is parsed from the output of "iw dev wlan0 survey dump".


=head1 CONFIGURATION

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

Root permissions are probably required for accessing "iw".

  [wireless_channel_occupation_*]
  user root


=head1 VERSION

  1.1


=head1 AUTHOR

Lars Kruse <devel@sumpfralle.de>


=head1 LICENSE

GPLv3 or above


=head1 MAGIC MARKERS

  #%# family=auto
  #%# capabilities=autoconf suggest

=cut

set -eu


SCRIPT_PREFIX="wireless_channel_occupation_"


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


get_wifi_interfaces() {
	iw dev | grep Interface | awk '{print $2}'
}

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


do_config() {
	local device
	local dev_field
	device=$(get_wifi_device_from_suffix)
	[ -z "$device" ] && echo >&2 "Invalid wifi device name given" && return 1
	echo "graph_title Channel Occupation of $device"
	echo "graph_vlabel %"
	echo "graph_category wireless"
	echo "graph_args --base 1000 -r --lower-limit 0 --upper-limit 100"
	dev_field=$(clean_fieldname "$device")

	# active: listening time on this channel (usually: 5 minutes = 300000ms)
	echo "${dev_field}_active.label Transmit"
	echo "${dev_field}_active.type DERIVE"
	echo "${dev_field}_active.graph no"

	# busy = receive + transmit + unknown
	echo "${dev_field}_busy.label unknown"
	echo "${dev_field}_busy.type DERIVE"
	echo "${dev_field}_busy.draw AREA"
	echo "${dev_field}_busy.cdef 100,1,${dev_field}_active,${dev_field}_busy,${dev_field}_receive,${dev_field}_transmit,+,-,/,/,*"

	# receive: this radio receives traffic for itself
	echo "${dev_field}_receive.label Receive"
	echo "${dev_field}_receive.type DERIVE"
	echo "${dev_field}_receive.draw STACK"
	echo "${dev_field}_receive.cdef 100,${dev_field}_receive,${dev_field}_active,/,*"

	# transmit: this radio transmits traffic
	echo "${dev_field}_transmit.label Transmit"
	echo "${dev_field}_transmit.type DERIVE"
	echo "${dev_field}_transmit.draw STACK"
	echo "${dev_field}_transmit.cdef 100,${dev_field}_transmit,${dev_field}_active,/,*"
}


do_fetch() {
	local device
	device=$(get_wifi_device_from_suffix)
	[ -z "$device" ] && echo >&2 "Invalid wifi device name given" && return 1
	iw dev "$device" survey dump \
		| grep -F -A 5 "[in use]" \
		| grep -E "channel (busy|receive|transmit|active) time:" \
		| awk '{print "'"${device}_"'"$2"'.value'",$4}'
}


if [ "${1:-}" = "autoconf" ]; then
	if which iw >/dev/null; then
		if [ -n "$(get_wifi_interfaces)" ]; then
			echo "yes"
		else
			echo "no (missing wifi devices)"
		fi
	else
		echo "no (missing 'iw' dependency)"
	fi
elif [ "${1:-}" = "suggest" ]; then
	for dev in $(get_wifi_interfaces); do
		clean_fieldname "$dev"
	done
elif [ "${1:-}" = "config" ]; then
	do_config || exit 1
	if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then do_fetch; fi
else
	do_fetch
fi

exit 0
