[PATCH 1/5] nodewatcher: split into nodewatcher.d scripts for individual task

Christian Dresel fff at chrisi01.de
Di Jan 7 15:13:52 CET 2020


Hi Adrian

grundlegende Frage, warum /usr/lib/nodewatcher.d? Die gateway.d  haben
wir in /etc liegen.

Zweite Frage: Es steht ja schon die Idee im Raum das ganze Zeug neu
sauber aufzubauen (vorallem Lemmi war da ja hinterher) und eine
ordentliche Datenstruktur hinzubekommen. Will man das in dem Zug vllt.
gleich mitmachen, sich eine ordentliche API im Monitoring überlegen und
das gleich damit umsetzen? Schade das du (und/oder Tim?) dir jetzt schon
die Arbeit gemacht hast und das alte Ding zerrupft hast.

Gruß

Christian

On 07.01.20 14:40, Adrian Schmutzler wrote:
> From: Tim Niemeyer <tim at tn-x.org>
> 
> This splits up the data extraction/assembly of the nodewatcher
> script into several parts and distributes them across packages, so
> that each nodewatcher.d subscript is located in the package providing
> the relevant functionality. This allows to extend the nodewatcher data
> by enabling/disabling packages.
> This scheme is not perfectly fulfilled for fff-network vs. fff-wireless,
> as data cannot uniquely assigned there and the XML syntax does not allow
> separation anyway.
> 
> In general, this moves code without applying code improvements, yielding
> at an easy comparison of moved fragments. However, the following changes
> were done to improve experience:
> 
> - The function writing debug output has been renamed from "err" to "debug"
> - Since we catch the stdout of the nodewatcher.d functions anyway,
>   those scripts were adjusted to echo output directly instead of first
>   writing it into a variable and then outputting it at the end.
> - The uci config has been kept, but initialization for the network part
>   has been moved to the fff-network package.
> - Space indent has been changed to tab, which is more common in the
>   firmware and requires less space.
> - Remove support for nodewatcher run without uci config. Script-based
>   nodewatcher on other platforms will have altered code anyway, and
>   splitting it up will prevent effective use as a blueprint for those
>   cases. After this change, nodewatcher in firmware is supposed to be
>   used only for this firmware.
> 
> Note that since the nodewatcher.d scripts are evaluated by using there
> echo output, having a function created uncaught output to stdout there
> will corrupt the XML.
> 
> Signed-off-by: Tim Niemeyer <tim at tn-x.org>
> [rebase and adjustments for current master, use simpler mechanism to
> call nodewatcher.d scripts, use tab indent, remove debug() definition
> where not needed, do not remove uci config, add commit message, use
> echo -n]
> Signed-off-by: Adrian Schmutzler <freifunk at adrianschmutzler.de>
> 
> ---
> 
> AFAIK POSIX shell does not support echo flags. Thus, we most probably
> should change /bin/sh to /bin/ash for all scripts?
> ---
>  src/packages/fff/fff-babeld/Makefile          |   2 +-
>  .../files/usr/lib/nodewatcher.d/80-babeld.sh  |  16 +
>  src/packages/fff/fff-batman-adv/Makefile      |   2 +-
>  .../usr/lib/nodewatcher.d/30-batman-adv.sh    |  60 ++++
>  src/packages/fff/fff-network/Makefile         |   2 +-
>  .../uci-defaults/94-fff-nodewatcher-network   |   9 +
>  .../usr/lib/nodewatcher.d/20-interfaces.sh    |  74 ++++
>  .../files/usr/lib/nodewatcher.d/50-clients.sh |  25 ++
>  src/packages/fff/fff-nodewatcher/Makefile     |   2 +-
>  .../files/etc/uci-defaults/93-fff-nodewatcher |   4 -
>  .../usr/lib/nodewatcher.d/10-systemdata.sh    | 123 +++++++
>  .../files/usr/sbin/nodewatcher                | 324 ++----------------
>  src/packages/fff/fff-wireless/Makefile        |   2 +-
>  .../files/usr/lib/nodewatcher.d/60-airtime.sh |  18 +
>  14 files changed, 361 insertions(+), 302 deletions(-)
>  create mode 100755 src/packages/fff/fff-babeld/files/usr/lib/nodewatcher.d/80-babeld.sh
>  create mode 100755 src/packages/fff/fff-batman-adv/files/usr/lib/nodewatcher.d/30-batman-adv.sh
>  create mode 100644 src/packages/fff/fff-network/files/etc/uci-defaults/94-fff-nodewatcher-network
>  create mode 100755 src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/20-interfaces.sh
>  create mode 100755 src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh
>  create mode 100755 src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh
>  create mode 100755 src/packages/fff/fff-wireless/files/usr/lib/nodewatcher.d/60-airtime.sh
> 
> diff --git a/src/packages/fff/fff-babeld/Makefile b/src/packages/fff/fff-babeld/Makefile
> index 29fd8e53..b2ccac89 100644
> --- a/src/packages/fff/fff-babeld/Makefile
> +++ b/src/packages/fff/fff-babeld/Makefile
> @@ -1,7 +1,7 @@
>  include $(TOPDIR)/rules.mk
>  
>  PKG_NAME:=fff-babeld
> -PKG_RELEASE:=1
> +PKG_RELEASE:=2
>  
>  PKG_BUILD_DIR:=$(BUILD_DIR)/fff-babeld
>  
> diff --git a/src/packages/fff/fff-babeld/files/usr/lib/nodewatcher.d/80-babeld.sh b/src/packages/fff/fff-babeld/files/usr/lib/nodewatcher.d/80-babeld.sh
> new file mode 100755
> index 00000000..80196970
> --- /dev/null
> +++ b/src/packages/fff/fff-babeld/files/usr/lib/nodewatcher.d/80-babeld.sh
> @@ -0,0 +1,16 @@
> +#!/bin/sh
> +
> +if pgrep babeld >/dev/null; then
> +	neighbours="$(echo dump | nc ::1 33123 | grep '^add neighbour' |
> +		awk '{
> +				for (i=2; i < NF; i += 2) {
> +					vars[$i] = $(i+1)
> +				}
> +			}
> +			{
> +				printf "<neighbour><ip>%s</ip><outgoing_interface>%s</outgoing_interface><link_cost>%s</link_cost></neighbour>", vars["address"], vars["if"], vars["cost"]
> +			}')"
> +	echo -n "<babel_neighbours>$neighbours</babel_neighbours>"
> +fi
> +
> +exit 0
> diff --git a/src/packages/fff/fff-batman-adv/Makefile b/src/packages/fff/fff-batman-adv/Makefile
> index 9ef58042..9d553dc0 100644
> --- a/src/packages/fff/fff-batman-adv/Makefile
> +++ b/src/packages/fff/fff-batman-adv/Makefile
> @@ -1,7 +1,7 @@
>  include $(TOPDIR)/rules.mk
>  
>  PKG_NAME:=fff-batman-adv
> -PKG_RELEASE:=1
> +PKG_RELEASE:=2
>  
>  PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
>  
> diff --git a/src/packages/fff/fff-batman-adv/files/usr/lib/nodewatcher.d/30-batman-adv.sh b/src/packages/fff/fff-batman-adv/files/usr/lib/nodewatcher.d/30-batman-adv.sh
> new file mode 100755
> index 00000000..37100a2d
> --- /dev/null
> +++ b/src/packages/fff/fff-batman-adv/files/usr/lib/nodewatcher.d/30-batman-adv.sh
> @@ -0,0 +1,60 @@
> +#!/bin/sh
> +# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
> +# License; GPL v3
> +
> +debug() {
> +	(>&2 echo "$1")
> +}
> +
> +debug "$(date): Collecting information from batman advanced and its interfaces"
> +#B.A.T.M.A.N. advanced
> +if [ -f /sys/module/batman_adv/version ]; then
> +	for iface in $(batctl if | sed 's/ //'); do
> +		status=${iface##*:}
> +		iface=${iface%%:*}
> +		BATMAN_ADV_INTERFACES=$BATMAN_ADV_INTERFACES"<$iface><name>$iface</name><status>$status</status></$iface>"
> +	done
> +
> +	echo -n "<batman_adv_interfaces>$BATMAN_ADV_INTERFACES</batman_adv_interfaces>"
> +
> +	# Build a list of direct neighbors
> +	batman_adv_originators=$(/usr/sbin/batctl o -H | awk \
> +		'BEGIN { FS=" "; i=0 } # set the delimiter to " "
> +		{   sub("\\(", "", $0) # remove parentheses
> +			sub("\\)", "", $0)
> +			sub("\\[", "", $0)
> +			sub("\\]", "", $0)
> +			sub("\\*", "", $0)
> +			sub("  ", " ", $0)
> +			o=$1".*"$1 # build a regex to find lines that contains the $1 (=originator) twice
> +			if ($0 ~ o) # filter for this regex (will remove entries without direct neighbor)
> +			{
> +				printf "<originator_"i"><originator>"$1"</originator><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><last_seen>"$2"</last_seen><outgoing_interface>"$5"</outgoing_interface></originator_"i">"
> +				i++
> +			}
> +		}')
> +
> +	echo -n "<batman_adv_originators>$batman_adv_originators</batman_adv_originators>"
> +
> +	echo -n "<batman_adv_gateway_mode>$(/usr/sbin/batctl gw)</batman_adv_gateway_mode>"
> +
> +	batman_adv_gateway_list=$(/usr/sbin/batctl gwl -H | awk \
> +		'BEGIN { FS=" "; i=0 }
> +		/No gateways/ { next }
> +		{   sub("\\(", "", $0)
> +			sub("\\)", "", $0)
> +			sub("\\[ *", "", $0)
> +			sub("\\]:", "", $0)
> +			sub("\\* ", "true ", $0)
> +			sub("  ", "false ", $0)
> +			printf "<gateway_"i"><selected>"$1"</selected><gateway>"$2"</gateway><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><outgoing_interface>"$5"</outgoing_interface><gw_class>"$6" "$7" "$8"</gw_class></gateway_"i">"
> +			i++
> +		}')
> +
> +	echo -n "<batman_adv_gateway_list>$batman_adv_gateway_list</batman_adv_gateway_list>"
> +else
> +	debug "$(date): No batman data .."
> +	exit 1
> +fi
> +
> +exit 0
> diff --git a/src/packages/fff/fff-network/Makefile b/src/packages/fff/fff-network/Makefile
> index 95f99e52..31928de8 100644
> --- a/src/packages/fff/fff-network/Makefile
> +++ b/src/packages/fff/fff-network/Makefile
> @@ -1,7 +1,7 @@
>  include $(TOPDIR)/rules.mk
>  
>  PKG_NAME:=fff-network
> -PKG_RELEASE:=12
> +PKG_RELEASE:=13
>  
>  PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
>  
> diff --git a/src/packages/fff/fff-network/files/etc/uci-defaults/94-fff-nodewatcher-network b/src/packages/fff/fff-network/files/etc/uci-defaults/94-fff-nodewatcher-network
> new file mode 100644
> index 00000000..353ab1b4
> --- /dev/null
> +++ b/src/packages/fff/fff-network/files/etc/uci-defaults/94-fff-nodewatcher-network
> @@ -0,0 +1,9 @@
> +uci batch <<EOF
> +  add nodewatcher network
> +  set nodewatcher. at network[-1].mesh_interface='br-mesh'
> +  set nodewatcher. at network[-1].iface_blacklist='lo ifb0'
> +  set nodewatcher. at network[-1].ip_whitelist='br-mesh'
> +EOF
> +uci commit nodewatcher
> +
> +exit 0
> diff --git a/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/20-interfaces.sh b/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/20-interfaces.sh
> new file mode 100755
> index 00000000..5373d6ef
> --- /dev/null
> +++ b/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/20-interfaces.sh
> @@ -0,0 +1,74 @@
> +#!/bin/sh
> +# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
> +# License; GPL v3
> +
> +IFACEBLACKLIST=$(uci get nodewatcher. at network[0].iface_blacklist)
> +IPWHITELIST=$(uci get nodewatcher. at network[0].ip_whitelist)
> +
> +debug() {
> +	(>&2 echo "$1")
> +}
> +
> +inArray() {
> +	local value
> +	for value in $1; do
> +		if [ "$value" = "$2" ]; then
> +			return 0
> +		fi
> +	done
> +	return 1
> +}
> +
> +debug "$(date): Collecting information from network interfaces"
> +
> +#Get interfaces
> +interface_data=""
> +#Loop interfaces
> +#for entry in $IFACES; do
> +for filename in $(grep 'up\|unknown' /sys/class/net/*/operstate); do
> +	ifpath=${filename%/operstate*}
> +	iface=${ifpath#/sys/class/net/}
> +	if inArray "$IFACEBLACKLIST" "$iface"; then
> +		continue
> +	fi
> +
> +	#Get interface data for whitelisted interfaces
> +	# shellcheck disable=SC2016
> +	awkscript='
> +		/ether/ { printf "<mac_addr>"$2"</mac_addr>" }
> +		/mtu/ { printf "<mtu>"$5"</mtu>" }'
> +	if inArray "$IPWHITELIST" "$iface"; then
> +		# shellcheck disable=SC2016
> +		awkscript=$awkscript'
> +			/inet / { split($2, a, "/"); printf "<ipv4_addr>"a[1]"</ipv4_addr>" }
> +			/inet6/ && /scope global/ { printf "<ipv6_addr>"$2"</ipv6_addr>" }
> +			/inet6/ && /scope link/ { printf "<ipv6_link_local_addr>"$2"</ipv6_link_local_addr>"}'
> +	fi
> +	addrs=$(ip addr show dev "${iface}" | awk "$awkscript")
> +
> +	traffic_rx=$(cat "$ifpath/statistics/rx_bytes")
> +	traffic_tx=$(cat "$ifpath/statistics/tx_bytes")
> +
> +	interface_data=$interface_data"<$iface><name>$iface</name>$addrs<traffic_rx>$traffic_rx</traffic_rx><traffic_tx>$traffic_tx</traffic_tx>"
> +
> +	interface_data=$interface_data$(iwconfig "${iface}" 2>/dev/null | awk -F':' '
> +		/Mode/{ split($2, m, " "); printf "<wlan_mode>"m[1]"</wlan_mode>" }
> +		/Cell/{ split($0, c, " "); printf "<wlan_bssid>"c[5]"</wlan_bssid>" }
> +		/ESSID/ { split($0, e, "\""); printf "<wlan_essid>"e[2]"</wlan_essid>" }
> +		/Freq/{ split($3, f, " "); printf "<wlan_frequency>"f[1]f[2]"</wlan_frequency>" }
> +		/Tx-Power/{ split($0, p, "="); sub(/[[:space:]]*$/, "", p[2]); printf "<wlan_tx_power>"p[2]"</wlan_tx_power>" }
> +	')
> +
> +	interface_data=$interface_data$(iw dev "${iface}" info 2>/dev/null | awk '
> +		/ssid/{ split($0, s, " "); printf "<wlan_ssid>"s[2]"</wlan_ssid>" }
> +		/type/ { split($0, t, " "); printf "<wlan_type>"t[2]"</wlan_type>" }
> +		/channel/{ split($0, c, " "); printf "<wlan_channel>"c[2]"</wlan_channel>" }
> +		/width/{ split($0, w, ": "); sub(/ .*/, "", w[2]); printf "<wlan_width>"w[2]"</wlan_width>" }
> +	')
> +
> +	interface_data=$interface_data"</$iface>"
> +done
> +
> +echo -n "<interface_data>$interface_data</interface_data>"
> +
> +exit 0
> diff --git a/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh b/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh
> new file mode 100755
> index 00000000..91d9b868
> --- /dev/null
> +++ b/src/packages/fff/fff-network/files/usr/lib/nodewatcher.d/50-clients.sh
> @@ -0,0 +1,25 @@
> +#!/bin/sh
> +# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
> +# License; GPL v3
> +
> +MESH_INTERFACE=$(uci get nodewatcher. at network[0].mesh_interface)
> +
> +debug() {
> +	(>&2 echo "$1")
> +}
> +
> +debug "$(date): Collecting information about connected clients"
> +
> +client_count=0
> +dataclient=""
> +CLIENT_INTERFACES=$(ls "/sys/class/net/$MESH_INTERFACE/brif" | grep -v '^bat')
> +for clientif in ${CLIENT_INTERFACES}; do
> +	local cc=$(bridge fdb show br "$MESH_INTERFACE" brport "$clientif" | grep -v self | grep -v permanent -c)
> +	client_count=$((client_count + cc))
> +	dataclient="$dataclient<$clientif>$cc</$clientif>"
> +done
> +
> +echo -n "<client_count>$client_count</client_count>"
> +echo -n "<clients>$dataclient</clients>"
> +
> +exit 0
> diff --git a/src/packages/fff/fff-nodewatcher/Makefile b/src/packages/fff/fff-nodewatcher/Makefile
> index 0ed6684d..423b7288 100644
> --- a/src/packages/fff/fff-nodewatcher/Makefile
> +++ b/src/packages/fff/fff-nodewatcher/Makefile
> @@ -1,7 +1,7 @@
>  include $(TOPDIR)/rules.mk
>  
>  PKG_NAME:=fff-nodewatcher
> -PKG_RELEASE:=55
> +PKG_RELEASE:=56
>  
>  PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
>  
> diff --git a/src/packages/fff/fff-nodewatcher/files/etc/uci-defaults/93-fff-nodewatcher b/src/packages/fff/fff-nodewatcher/files/etc/uci-defaults/93-fff-nodewatcher
> index 4e564352..0fc2e90e 100644
> --- a/src/packages/fff/fff-nodewatcher/files/etc/uci-defaults/93-fff-nodewatcher
> +++ b/src/packages/fff/fff-nodewatcher/files/etc/uci-defaults/93-fff-nodewatcher
> @@ -8,10 +8,6 @@ uci batch <<EOF
>    set nodewatcher. at script[0].logfile='/var/log/nodewatcher.log'
>    set nodewatcher. at script[0].data_file='/tmp/crawldata/node.data'
>    set nodewatcher. at script[0].status_text_file='/tmp/status.txt'
> -  add nodewatcher network
> -  set nodewatcher. at network[0].mesh_interface='br-mesh'
> -  set nodewatcher. at network[0].iface_blacklist='lo ifb0'
> -  set nodewatcher. at network[0].ip_whitelist='br-mesh'
>  EOF
>  uci commit
>  
> diff --git a/src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh b/src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh
> new file mode 100755
> index 00000000..713cea6c
> --- /dev/null
> +++ b/src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh
> @@ -0,0 +1,123 @@
> +#!/bin/sh
> +# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
> +# License; GPL v3
> +
> +SCRIPT_STATUS_FILE=$(uci get nodewatcher. at script[0].status_text_file)
> +SCRIPT_VERSION="56"
> +
> +debug() {
> +	(>&2 echo "$1")
> +}
> +
> +#Get system data from other locations
> +debug "$(date): Collecting basic system status data"
> +hostname="$(cat /proc/sys/kernel/hostname)"
> +mac=$(awk '{ mac=toupper($1); gsub(":", "", mac); print mac }' /sys/class/net/br-mesh/address 2>/dev/null)
> +[ "$hostname" = "OpenWrt" ] && hostname="$mac"
> +[ "$hostname" = "FFF" ] && hostname="$mac"
> +description="$(uci -q get fff.system.description)"
> +if [ -n "$description" ]; then
> +	description="<description><![CDATA[$description]]></description>"
> +fi
> +latitude="$(uci -q get fff.system.latitude)"
> +longitude="$(uci -q get fff.system.longitude)"
> +if [ -n "$longitude" -a -n "$latitude" ]; then
> +	geo="<geo><lat>$latitude</lat><lng>$longitude</lng></geo>";
> +fi
> +position_comment="$(uci -q get fff.system.position_comment)"
> +if [ -n "$position_comment" ]; then
> +	position_comment="<position_comment><![CDATA[$position_comment]]></position_comment>"
> +fi
> +contact="$(uci -q get fff.system.contact)"
> +if [ -n "$contact" ]; then
> +	contact="<contact>$contact</contact>"
> +fi
> +uptime=$(awk '{ printf "<uptime>"$1"</uptime><idletime>"$2"</idletime>" }' /proc/uptime)
> +
> +memory=$(awk '
> +	/^MemTotal/ { printf "<memory_total>"$2"</memory_total>" }
> +	/^Cached:/ { printf "<memory_caching>"$2"</memory_caching>" }
> +	/^Buffers/ { printf "<memory_buffering>"$2"</memory_buffering>" }
> +	/^MemFree/ { printf "<memory_free>"$2"</memory_free>" }
> +' /proc/meminfo)
> +cpu=$(awk -F': ' '
> +	/model/ { printf "<cpu>"$2"</cpu>" }
> +	/system type/ { printf "<chipset>"$2"</chipset>" }
> +	/platform/ { printf "<chipset>"$2"</chipset>" }
> +' /proc/cpuinfo)
> +model="<model>$(cat /var/sysinfo/model)</model>"
> +local_time="$(date +%s)"
> +load=$(awk '{ printf "<loadavg>"$3"</loadavg><processes>"$4"</processes>" }' /proc/loadavg)
> +
> +debug "$(date): Collecting version information"
> +
> +batman_adv_version=$(cat /sys/module/batman_adv/version)
> +kernel_version=$(uname -r)
> +if [ -x /usr/bin/fastd ]; then
> +	fastd_version="<fastd_version>$(/usr/bin/fastd -v | awk '{ print $2 }')</fastd_version>"
> +fi
> +nodewatcher_version=$SCRIPT_VERSION
> +if [ -x /usr/sbin/babeld ]; then
> +	babel_version="<babel_version>$(/usr/sbin/babeld -V 2>&1)</babel_version>"
> +fi
> +
> +if [ -f "$SCRIPT_STATUS_FILE" ]; then
> +	status_text="<status_text>$(cat "$SCRIPT_STATUS_FILE")</status_text>"
> +fi
> +
> +# Checks if fastd is running
> +if pidof fastd >/dev/null ; then
> +	vpn_active="<vpn_active>1</vpn_active>"
> +else
> +	vpn_active="<vpn_active>0</vpn_active>"
> +fi
> +
> +# example for /etc/openwrt_release:
> +#DISTRIB_ID="OpenWrt"
> +#DISTRIB_RELEASE="Attitude Adjustment"
> +#DISTRIB_REVISION="r35298"
> +#DISTRIB_CODENAME="attitude_adjustment"
> +#DISTRIB_TARGET="atheros/generic"
> +#DISTRIB_DESCRIPTION="OpenWrt Attitude Adjustment 12.09-rc1"
> +. /etc/openwrt_release
> +distname=$DISTRIB_ID
> +distversion=$DISTRIB_RELEASE
> +
> +# example for /etc/firmware_release:
> +#FIRMWARE_VERSION="95f36685e7b6cbf423f02cf5c7f1e785fd4ccdae-dirty"
> +#BUILD_DATE="build date: Di 29. Jan 19:33:34 CET 2013"
> +#OPENWRT_CORE_REVISION="35298"
> +#OPENWRT_FEEDS_PACKAGES_REVISION="35298"
> +. /etc/firmware_release
> +
> +SYSTEM_DATA="<status>online</status>"
> +SYSTEM_DATA=$SYSTEM_DATA"$status_text"
> +SYSTEM_DATA=$SYSTEM_DATA"<hostname>$hostname</hostname>"
> +SYSTEM_DATA=$SYSTEM_DATA"${description}"
> +SYSTEM_DATA=$SYSTEM_DATA"${geo}"
> +SYSTEM_DATA=$SYSTEM_DATA"${position_comment}"
> +SYSTEM_DATA=$SYSTEM_DATA"${contact}"
> +SYSTEM_DATA=$SYSTEM_DATA"<hood>$(uci -q get "system. at system[0].hood")</hood>"
> +SYSTEM_DATA=$SYSTEM_DATA"<hoodid>$(uci -q get "system. at system[0].hoodid")</hoodid>"
> +SYSTEM_DATA=$SYSTEM_DATA"<distname>$distname</distname>"
> +SYSTEM_DATA=$SYSTEM_DATA"<distversion>$distversion</distversion>"
> +SYSTEM_DATA=$SYSTEM_DATA"$cpu"
> +SYSTEM_DATA=$SYSTEM_DATA"$model"
> +SYSTEM_DATA=$SYSTEM_DATA"$memory"
> +SYSTEM_DATA=$SYSTEM_DATA"$load"
> +SYSTEM_DATA=$SYSTEM_DATA"$uptime"
> +SYSTEM_DATA=$SYSTEM_DATA"<local_time>$local_time</local_time>"
> +SYSTEM_DATA=$SYSTEM_DATA"<batman_advanced_version>$batman_adv_version</batman_advanced_version>"
> +SYSTEM_DATA=$SYSTEM_DATA"<kernel_version>$kernel_version</kernel_version>"
> +SYSTEM_DATA=$SYSTEM_DATA"$fastd_version"
> +SYSTEM_DATA=$SYSTEM_DATA"<nodewatcher_version>$nodewatcher_version</nodewatcher_version>"
> +SYSTEM_DATA=$SYSTEM_DATA"$babel_version"
> +SYSTEM_DATA=$SYSTEM_DATA"<firmware_version>$FIRMWARE_VERSION</firmware_version>"
> +SYSTEM_DATA=$SYSTEM_DATA"<firmware_revision>$BUILD_DATE</firmware_revision>"
> +SYSTEM_DATA=$SYSTEM_DATA"<openwrt_core_revision>$OPENWRT_CORE_REVISION</openwrt_core_revision>"
> +SYSTEM_DATA=$SYSTEM_DATA"<openwrt_feeds_packages_revision>$OPENWRT_FEEDS_PACKAGES_REVISION</openwrt_feeds_packages_revision>"
> +SYSTEM_DATA=$SYSTEM_DATA"$vpn_active"
> +
> +echo -n "<system_data>$SYSTEM_DATA</system_data>"
> +
> +exit 0
> diff --git a/src/packages/fff/fff-nodewatcher/files/usr/sbin/nodewatcher b/src/packages/fff/fff-nodewatcher/files/usr/sbin/nodewatcher
> index 42e5ce8f..21880fbe 100755
> --- a/src/packages/fff/fff-nodewatcher/files/usr/sbin/nodewatcher
> +++ b/src/packages/fff/fff-nodewatcher/files/usr/sbin/nodewatcher
> @@ -7,327 +7,65 @@ test -f /tmp/started || exit
>  # Allow only one instance
>  lockfile="/var/lock/${0##*/}.lock"
>  if ! lock -n "$lockfile"; then
> -        echo "Only one instance of $0 allowed."
> -        exit 1
> +	echo "Only one instance of $0 allowed."
> +	exit 1
>  fi
>  trap "lock -u \"$lockfile\"" INT TERM EXIT
>  
> -SCRIPT_VERSION="55"
> +[ -s /etc/config/nodewatcher ] || exit 1
>  
> -#Get the configuration from the uci configuration file
> -#If it does not exists, then get it from a normal bash file with variables.
> -if [ -f /etc/config/nodewatcher ];then
> -    SCRIPT_ERROR_LEVEL=$(uci get nodewatcher. at script[0].error_level)
> -    SCRIPT_LOGFILE=$(uci get nodewatcher. at script[0].logfile)
> -    SCRIPT_DATA_FILE=$(uci get nodewatcher. at script[0].data_file)
> -    MESH_INTERFACE=$(uci get nodewatcher. at network[0].mesh_interface)
> -    IFACEBLACKLIST=$(uci get nodewatcher. at network[0].iface_blacklist)
> -    IPWHITELIST=$(uci get nodewatcher. at network[0].ip_whitelist)
> -    SCRIPT_STATUS_FILE=$(uci get nodewatcher. at script[0].status_text_file)
> -else
> -    . "$(dirname "$0")/nodewatcher_config"
> -fi
> +SCRIPT_ERROR_LEVEL=$(uci get nodewatcher. at script[0].error_level)
> +SCRIPT_LOGFILE=$(uci get nodewatcher. at script[0].logfile)
> +SCRIPT_DATA_FILE=$(uci get nodewatcher. at script[0].data_file)
>  
>  if [ "$SCRIPT_ERROR_LEVEL" -gt "1" ]; then
> -    err() {
> -        echo "$1" >> "$SCRIPT_LOGFILE"
> -    }
> +	debug() {
> +		echo "$1" >> "$SCRIPT_LOGFILE"
> +	}
>  else
> -    err() {
> -        :
> -    }
> +	debug() {
> +		:
> +	}
>  fi
>  
>  #This method checks if the log file has become too big and deletes the first X lines
>  delete_log() {
> -    if [ -f "$SCRIPT_LOGFILE" ]; then
> -        if [ "$(find "$SCRIPT_LOGFILE" -printf "%s")" -gt "6000" ]; then
> -            sed -i '1,60d' "$SCRIPT_LOGFILE"
> -            err "$(date): Logfile has been made smaller"
> -        fi
> -    fi
> -}
> -
> -inArray() {
> -    local value
> -    for value in $1; do
> -        if [ "$value" = "$2" ]; then
> -            return 0
> -        fi
> -    done
> -    return 1
> +	if [ -f "$SCRIPT_LOGFILE" ]; then
> +		if [ "$(find "$SCRIPT_LOGFILE" -printf "%s")" -gt "6000" ]; then
> +			sed -i '1,60d' "$SCRIPT_LOGFILE"
> +			debug "$(date): Logfile has been made smaller"
> +		fi
> +	fi
>  }
>  
>  #This method generates the crawl data XML file that is being fetched by netmon
>  #and provided by a small local httpd
>  crawl() {
> -    #Get system data from other locations
> -    err "$(date): Collecting basic system status data"
> -    hostname="$(cat /proc/sys/kernel/hostname)"
> -    mac=$(awk '{ mac=toupper($1); gsub(":", "", mac); print mac }' /sys/class/net/br-mesh/address 2>/dev/null)
> -    [ "$hostname" = "OpenWrt" ] && hostname="$mac"
> -    [ "$hostname" = "FFF" ] && hostname="$mac"
> -    description="$(uci -q get fff.system.description)"
> -    if [ -n "$description" ]; then
> -        description="<description><![CDATA[$description]]></description>"
> -    fi
> -    latitude="$(uci -q get fff.system.latitude)"
> -    longitude="$(uci -q get fff.system.longitude)"
> -    if [ -n "$longitude" -a -n "$latitude" ]; then
> -        geo="<geo><lat>$latitude</lat><lng>$longitude</lng></geo>";
> -    fi
> -    position_comment="$(uci -q get fff.system.position_comment)"
> -    if [ -n "$position_comment" ]; then
> -        position_comment="<position_comment><![CDATA[$position_comment]]></position_comment>"
> -    fi
> -    contact="$(uci -q get fff.system.contact)"
> -    if [ -n "$contact" ]; then
> -        contact="<contact>$contact</contact>"
> -    fi
> -    uptime=$(awk '{ printf "<uptime>"$1"</uptime><idletime>"$2"</idletime>" }' /proc/uptime)
> -
> -    memory=$(awk '
> -        /^MemTotal/ { printf "<memory_total>"$2"</memory_total>" }
> -        /^Cached:/ { printf "<memory_caching>"$2"</memory_caching>" }
> -        /^Buffers/ { printf "<memory_buffering>"$2"</memory_buffering>" }
> -        /^MemFree/ { printf "<memory_free>"$2"</memory_free>" }
> -    ' /proc/meminfo)
> -    cpu=$(awk -F': ' '
> -        /model/ { printf "<cpu>"$2"</cpu>" }
> -        /system type/ { printf "<chipset>"$2"</chipset>" }
> -        /platform/ { printf "<chipset>"$2"</chipset>" }
> -    ' /proc/cpuinfo)
> -    model="<model>$(cat /var/sysinfo/model)</model>"
> -    local_time="$(date +%s)"
> -    load=$(awk '{ printf "<loadavg>"$3"</loadavg><processes>"$4"</processes>" }' /proc/loadavg)
> -
> -    err "$(date): Collecting version information"
> -
> -    batman_adv_version=$(cat /sys/module/batman_adv/version)
> -    kernel_version=$(uname -r)
> -    if [ -x /usr/bin/fastd ]; then
> -        fastd_version="<fastd_version>$(/usr/bin/fastd -v | awk '{ print $2 }')</fastd_version>"
> -    fi
> -    nodewatcher_version=$SCRIPT_VERSION
> -    if [ -x /usr/sbin/babeld ]; then
> -        babel_version="<babel_version>$(/usr/sbin/babeld -V 2>&1)</babel_version>"
> -    fi
> -
> -    if [ -f "$SCRIPT_STATUS_FILE" ]; then
> -        status_text="<status_text>$(cat "$SCRIPT_STATUS_FILE")</status_text>"
> -    fi
> -
> -    # Checks if fastd is running
> -    if pidof fastd >/dev/null ; then
> -        vpn_active="<vpn_active>1</vpn_active>"
> -    else
> -        vpn_active="<vpn_active>0</vpn_active>"
> -    fi
> -
> -    # example for /etc/openwrt_release:
> -    #DISTRIB_ID="OpenWrt"
> -    #DISTRIB_RELEASE="Attitude Adjustment"
> -    #DISTRIB_REVISION="r35298"
> -    #DISTRIB_CODENAME="attitude_adjustment"
> -    #DISTRIB_TARGET="atheros/generic"
> -    #DISTRIB_DESCRIPTION="OpenWrt Attitude Adjustment 12.09-rc1"
> -    . /etc/openwrt_release
> -    distname=$DISTRIB_ID
> -    distversion=$DISTRIB_RELEASE
> -
> -    # example for /etc/firmware_release:
> -    #FIRMWARE_VERSION="95f36685e7b6cbf423f02cf5c7f1e785fd4ccdae-dirty"
> -    #BUILD_DATE="build date: Di 29. Jan 19:33:34 CET 2013"
> -    #OPENWRT_CORE_REVISION="35298"
> -    #OPENWRT_FEEDS_PACKAGES_REVISION="35298"
> -    . /etc/firmware_release
> -
> -    SYSTEM_DATA="<status>online</status>"
> -    SYSTEM_DATA=$SYSTEM_DATA"$status_text"
> -    SYSTEM_DATA=$SYSTEM_DATA"<hostname>$hostname</hostname>"
> -    SYSTEM_DATA=$SYSTEM_DATA"${description}"
> -    SYSTEM_DATA=$SYSTEM_DATA"${geo}"
> -    SYSTEM_DATA=$SYSTEM_DATA"${position_comment}"
> -    SYSTEM_DATA=$SYSTEM_DATA"${contact}"
> -    SYSTEM_DATA=$SYSTEM_DATA"<hood>$(uci -q get "system. at system[0].hood")</hood>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<hoodid>$(uci -q get "system. at system[0].hoodid")</hoodid>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<distname>$distname</distname>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<distversion>$distversion</distversion>"
> -    SYSTEM_DATA=$SYSTEM_DATA"$cpu"
> -    SYSTEM_DATA=$SYSTEM_DATA"$model"
> -    SYSTEM_DATA=$SYSTEM_DATA"$memory"
> -    SYSTEM_DATA=$SYSTEM_DATA"$load"
> -    SYSTEM_DATA=$SYSTEM_DATA"$uptime"
> -    SYSTEM_DATA=$SYSTEM_DATA"<local_time>$local_time</local_time>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<batman_advanced_version>$batman_adv_version</batman_advanced_version>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<kernel_version>$kernel_version</kernel_version>"
> -    SYSTEM_DATA=$SYSTEM_DATA"$fastd_version"
> -    SYSTEM_DATA=$SYSTEM_DATA"<nodewatcher_version>$nodewatcher_version</nodewatcher_version>"
> -    SYSTEM_DATA=$SYSTEM_DATA"$babel_version"
> -    SYSTEM_DATA=$SYSTEM_DATA"<firmware_version>$FIRMWARE_VERSION</firmware_version>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<firmware_revision>$BUILD_DATE</firmware_revision>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<openwrt_core_revision>$OPENWRT_CORE_REVISION</openwrt_core_revision>"
> -    SYSTEM_DATA=$SYSTEM_DATA"<openwrt_feeds_packages_revision>$OPENWRT_FEEDS_PACKAGES_REVISION</openwrt_feeds_packages_revision>"
> -    SYSTEM_DATA=$SYSTEM_DATA"$vpn_active"
> -
> -    err "$(date): Collecting information from network interfaces"
> -
> -    #Get interfaces
> -    interface_data=""
> -    #Loop interfaces
> -    #for entry in $IFACES; do
> -    for filename in $(grep 'up\|unknown' /sys/class/net/*/operstate); do
> -        ifpath=${filename%/operstate*}
> -        iface=${ifpath#/sys/class/net/}
> -        if inArray "$IFACEBLACKLIST" "$iface"; then
> -            continue
> -        fi
> -
> -        #Get interface data for whitelisted interfaces
> -        # shellcheck disable=SC2016
> -        awkscript='
> -            /ether/ { printf "<mac_addr>"$2"</mac_addr>" }
> -            /mtu/ { printf "<mtu>"$5"</mtu>" }'
> -        if inArray "$IPWHITELIST" "$iface"; then
> -            # shellcheck disable=SC2016
> -            awkscript=$awkscript'
> -                /inet / { split($2, a, "/"); printf "<ipv4_addr>"a[1]"</ipv4_addr>" }
> -                /inet6/ && /scope global/ { printf "<ipv6_addr>"$2"</ipv6_addr>" }
> -                /inet6/ && /scope link/ { printf "<ipv6_link_local_addr>"$2"</ipv6_link_local_addr>"}'
> -        fi
> -        addrs=$(ip addr show dev "${iface}" | awk "$awkscript")
> -
> -        traffic_rx=$(cat "$ifpath/statistics/rx_bytes")
> -        traffic_tx=$(cat "$ifpath/statistics/tx_bytes")
> -
> -        interface_data=$interface_data"<$iface><name>$iface</name>$addrs<traffic_rx>$traffic_rx</traffic_rx><traffic_tx>$traffic_tx</traffic_tx>"
> -
> -        interface_data=$interface_data$(iwconfig "${iface}" 2>/dev/null | awk -F':' '
> -            /Mode/{ split($2, m, " "); printf "<wlan_mode>"m[1]"</wlan_mode>" }
> -            /Cell/{ split($0, c, " "); printf "<wlan_bssid>"c[5]"</wlan_bssid>" }
> -            /ESSID/ { split($0, e, "\""); printf "<wlan_essid>"e[2]"</wlan_essid>" }
> -            /Freq/{ split($3, f, " "); printf "<wlan_frequency>"f[1]f[2]"</wlan_frequency>" }
> -            /Tx-Power/{ split($0, p, "="); sub(/[[:space:]]*$/, "", p[2]); printf "<wlan_tx_power>"p[2]"</wlan_tx_power>" }
> -        ')
> -
> -        interface_data=$interface_data$(iw dev "${iface}" info 2>/dev/null | awk '
> -            /ssid/{ split($0, s, " "); printf "<wlan_ssid>"s[2]"</wlan_ssid>" }
> -            /type/ { split($0, t, " "); printf "<wlan_type>"t[2]"</wlan_type>" }
> -            /channel/{ split($0, c, " "); printf "<wlan_channel>"c[2]"</wlan_channel>" }
> -            /width/{ split($0, w, ": "); sub(/ .*/, "", w[2]); printf "<wlan_width>"w[2]"</wlan_width>" }
> -        ')
> -
> -        interface_data=$interface_data"</$iface>"
> -    done
> -
> -    err "$(date): Collecting information from batman advanced and its interfaces"
> -    #B.A.T.M.A.N. advanced
> -    if [ -f /sys/module/batman_adv/version ]; then
> -        for iface in $(batctl if | sed 's/ //'); do
> -            status=${iface##*:}
> -            iface=${iface%%:*}
> -            BATMAN_ADV_INTERFACES=$BATMAN_ADV_INTERFACES"<$iface><name>$iface</name><status>$status</status></$iface>"
> -        done
> -
> -        # Build a list of direct neighbors
> -        batman_adv_originators=$(/usr/sbin/batctl o -H | awk \
> -            'BEGIN { FS=" "; i=0 } # set the delimiter to " "
> -            {   sub("\\(", "", $0) # remove parentheses
> -                sub("\\)", "", $0)
> -                sub("\\[", "", $0)
> -                sub("\\]", "", $0)
> -                sub("\\*", "", $0)
> -                sub("  ", " ", $0)
> -                o=$1".*"$1 # build a regex to find lines that contains the $1 (=originator) twice
> -                if ($0 ~ o) # filter for this regex (will remove entries without direct neighbor)
> -                {
> -                    printf "<originator_"i"><originator>"$1"</originator><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><last_seen>"$2"</last_seen><outgoing_interface>"$5"</outgoing_interface></originator_"i">"
> -                    i++
> -                }
> -            }')
> -
> -        batman_adv_gateway_mode=$(/usr/sbin/batctl gw)
> -
> -        batman_adv_gateway_list=$(/usr/sbin/batctl gwl -H | awk \
> -            'BEGIN { FS=" "; i=0 }
> -            /No gateways/ { next }
> -            {   sub("\\(", "", $0)
> -                sub("\\)", "", $0)
> -                sub("\\[ *", "", $0)
> -                sub("\\]:", "", $0)
> -                sub("\\* ", "true ", $0)
> -                sub("  ", "false ", $0)
> -                printf "<gateway_"i"><selected>"$1"</selected><gateway>"$2"</gateway><link_quality>"$3"</link_quality><nexthop>"$4"</nexthop><outgoing_interface>"$5"</outgoing_interface><gw_class>"$6" "$7" "$8"</gw_class></gateway_"i">"
> -                i++
> -            }')
> -    fi
> -    err "$(date): Collecting information about conected clients"
> -    #CLIENTS
> -    client_count=0
> -    dataclient=""
> -    CLIENT_INTERFACES=$(ls "/sys/class/net/$MESH_INTERFACE/brif" | grep -v '^bat')
> -    for clientif in ${CLIENT_INTERFACES}; do
> -        local cc=$(bridge fdb show br "$MESH_INTERFACE" brport "$clientif" | grep -v self | grep -v permanent -c)
> -        client_count=$((client_count + cc))
> -        dataclient="$dataclient<$clientif>$cc</$clientif>"
> -    done
> -
> -    dataair=""
> -    w2dump="$(iw dev w2ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
> -    if [ -n "$w2dump" ] ; then
> -        w2_ACT="$(ACTIVE=$(echo "$w2dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
> -        w2_BUS="$(BUSY=$(echo "$w2dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
> -        dataair="$dataair<airtime2><active>$w2_ACT</active><busy>$w2_BUS</busy></airtime2>"
> -    fi
> -    w5dump="$(iw dev w5ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
> -    if [ -n "$w5dump" ] ; then
> -        w5_ACT="$(ACTIVE=$(echo "$w5dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
> -        w5_BUS="$(BUSY=$(echo "$w5dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
> -        dataair="$dataair<airtime5><active>$w5_ACT</active><busy>$w5_BUS</busy></airtime5>"
> -    fi
> +	debug "$(date): Putting all information into a XML-File and save it at $SCRIPT_DATA_FILE"
>  
> -    if pgrep babeld >/dev/null; then
> -        neighbours="$(echo dump | nc ::1 33123 | grep '^add neighbour' |
> -            awk '{
> -                   for (i=2; i < NF; i += 2) {
> -                     vars[$i] = $(i+1)
> -                   }
> -                 }
> -                 {
> -                   printf "<neighbour><ip>%s</ip><outgoing_interface>%s</outgoing_interface><link_cost>%s</link_cost></neighbour>", vars["address"], vars["if"], vars["cost"]
> -                 }')"
> -        BABELS="<babel_neighbours>$neighbours</babel_neighbours>"
> -    fi
> +	DATA="<?xml version='1.0' standalone='yes'?><data>"
>  
> -    err "$(date): Putting all information into a XML-File and save it at $SCRIPT_DATA_FILE"
> +	for f in /usr/lib/nodewatcher.d/*.sh; do
> +		tmp="$($f)"
> +		DATA="$DATA$tmp"
> +	done
>  
> -    DATA="<?xml version='1.0' standalone='yes'?><data>"
> -    DATA=$DATA"<system_data>$SYSTEM_DATA</system_data>"
> -    DATA=$DATA"<interface_data>$interface_data</interface_data>"
> -    DATA=$DATA"<batman_adv_interfaces>$BATMAN_ADV_INTERFACES</batman_adv_interfaces>"
> -    DATA=$DATA"<batman_adv_originators>$batman_adv_originators</batman_adv_originators>"
> -    DATA=$DATA"<batman_adv_gateway_mode>$batman_adv_gateway_mode</batman_adv_gateway_mode>"
> -    DATA=$DATA"<batman_adv_gateway_list>$batman_adv_gateway_list</batman_adv_gateway_list>"
> -    DATA=$DATA"$BABELS"
> -    DATA=$DATA"<client_count>$client_count</client_count>"
> -    DATA=$DATA"<clients>$dataclient</clients>"
> -    DATA=$DATA"$dataair"
> -    DATA=$DATA"</data>"
> +	DATA="$DATA</data>"
>  
> -    #write data to xml file that provides the data on httpd
> -    SCRIPT_DATA_DIR=$(dirname "$SCRIPT_DATA_FILE")
> -    test -d "$SCRIPT_DATA_DIR" || mkdir -p "$SCRIPT_DATA_DIR"
> -    echo "$DATA" | gzip | tee "$SCRIPT_DATA_FILE" | alfred -s 64
> +	#write data to xml file that provides the data on httpd
> +	SCRIPT_DATA_DIR=$(dirname "$SCRIPT_DATA_FILE")
> +	test -d "$SCRIPT_DATA_DIR" || mkdir -p "$SCRIPT_DATA_DIR"
> +	echo "$DATA" | gzip | tee "$SCRIPT_DATA_FILE" | alfred -s 64
>  }
>  
>  LANG=C
>  
>  #Prüft ob das logfile zu groß geworden ist
> -err "$(date): Check logfile"
> +debug "$(date): Check logfile"
>  delete_log
>  
>  #Erzeugt die statusdaten
> -err "$(date): Generate actual status data"
> +debug "$(date): Generate actual status data"
>  crawl
>  
>  exit 0
> diff --git a/src/packages/fff/fff-wireless/Makefile b/src/packages/fff/fff-wireless/Makefile
> index 00b1c7ca..e805ea22 100644
> --- a/src/packages/fff/fff-wireless/Makefile
> +++ b/src/packages/fff/fff-wireless/Makefile
> @@ -1,7 +1,7 @@
>  include $(TOPDIR)/rules.mk
>  
>  PKG_NAME:=fff-wireless
> -PKG_RELEASE:=13
> +PKG_RELEASE:=14
>  
>  PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
>  
> diff --git a/src/packages/fff/fff-wireless/files/usr/lib/nodewatcher.d/60-airtime.sh b/src/packages/fff/fff-wireless/files/usr/lib/nodewatcher.d/60-airtime.sh
> new file mode 100755
> index 00000000..ca53d904
> --- /dev/null
> +++ b/src/packages/fff/fff-wireless/files/usr/lib/nodewatcher.d/60-airtime.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh
> +# Netmon Nodewatcher (C) 2010-2012 Freifunk Oldenburg
> +# License; GPL v3
> +
> +w2dump="$(iw dev w2ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
> +if [ -n "$w2dump" ] ; then
> +	w2_ACT="$(ACTIVE=$(echo "$w2dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
> +	w2_BUS="$(BUSY=$(echo "$w2dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
> +	echo -n "$dataair<airtime2><active>$w2_ACT</active><busy>$w2_BUS</busy></airtime2>"
> +fi
> +w5dump="$(iw dev w5ap survey dump 2> /dev/null | sed '/Survey/,/\[in use\]/d')"
> +if [ -n "$w5dump" ] ; then
> +	w5_ACT="$(ACTIVE=$(echo "$w5dump" | grep "active time:"); set ${ACTIVE:-0 0 0 0 0}; echo -e "${4}")"
> +	w5_BUS="$(BUSY=$(echo "$w5dump" | grep "busy time:"); set ${BUSY:-0 0 0 0 0}; echo -e "${4}")"
> +	echo -n "$dataair<airtime5><active>$w5_ACT</active><busy>$w5_BUS</busy></airtime5>"
> +fi
> +
> +exit 0
> 


Mehr Informationen über die Mailingliste franken-dev