#!/bin/sh
# tlp-rdw - network manager dispatcher hook:
#           enable/disable radios on ifup/ifdown
#
# Copyright (c) 2015 Thomas Koch <linrunner at gmx.net>
# This software is licensed under the GPL v2 or later.

# --- Constants
readonly LIBDIRS="/usr/lib/tlp-pm /usr/lib64/tlp-pm"
readonly LIBS="tlp-functions tlp-rf-func"

readonly RDW_NM_LOCK="rdw_nm"
readonly RDW_NM_LOCKTIME=2

# --- Locate and source libraries
for libdir in $LIBDIRS; do [ -d $libdir ] && break; done
[ -d $libdir ] || exit 0

for lib in $LIBS; do
    [ -f $libdir/$lib ] || exit 0
    . $libdir/$lib
done

# --- MAIN
read_defaults
check_tlp_enabled || exit 0
add_sbin2path

# Get args
iface="$1"
action="$2"
itype="unknown"

# Quit for invalid interfaces
[ -n "$iface" ] && [ "$iface" != "none" ] || exit 0

echo_debug "nm" "rdw_nm($iface).$action"
if [ -n "$addpath" ]; then
    echo_debug "path" "PATH=$oldpath[$addpath]"
else
    echo_debug "path" "PATH=$oldpath"
fi

# Quit if timed lock in progress
check_timed_lock $RDW_NM_LOCK && exit 0

# Determine interface type
if cmd_exists $NMCLI ; then
    # nmcli is available
    itype="$($NMCLI dev | awk '$1 ~ /'$iface'/ { print $2; }')"

    if [ -z "$itype" ]; then
        itype="unknown"

        case $iface in
            ppp*|wwan*) # iface != device -> maybe 3g card or usb stick?

                # get connection state for devices != hso|usb|wwan
                nmstate=$($NMCLI dev | grep 'gsm' | egrep -v 'hso|usb|wwan' | awk '{ print $3; }')

                # when action matches state, then it is probably type 3g/gsm
                case $action in
                    up) [ "$nmstate" = "connected" ] && itype="gsm" ;;
                    down) [ "$nmstate" = "disconnected" ] && itype="gsm" ;;
                esac
                ;;
        esac
    fi

    echo_debug "nm" "rdw_nm($iface).$action: type=$itype [nmcli]"
else
    # nmcli is not available, fallback to nm-tool
    case $iface in
        ppp*) # iface != device -> maybe 3g usb stick?

            # get connection state for devices != hso|usb|wwan
            nmstate=$($NMTOOL | egrep -v 'Device:.*(hso|usb|wwan)' | grep -A3 'Device:' \
                              | grep -A2 'Mobile Broadband (GSM)'  | grep 'State:' \
                              | awk '{ print $2; }')

            # when action matches state, then it is probably type 3g/gsm
            case $action in
                up) [ "$nmstate" = "connected" ] && itype="gsm" ;;
                down) [ "$nmstate" = "disconnected" ] && itype="gsm" ;;
            esac
            ;;

        *) # iface = dev -> all other devices, including 3g with specific driver
            nmtype=$($NMTOOL | grep -A1 $iface | grep 'Type:' | cut -c22-)
            case $nmtype in
                "Wired") itype="802-3-ethernet" ;;
                "802.11 WiFi") itype="802-11-wireless" ;;
                "Mobile Broadband (GSM)") itype="gsm" ;;
            esac
            ;;
    esac

    echo_debug "nm" "rdw_nm($iface).$action: type=$itype [nm-tool]"
fi

case $action in
    up) # interface up, disable configured interfaces

        set_timed_lock $RDW_NM_LOCK $RDW_NM_LOCKTIME # lock rdw events

        case $itype in
            *ethernet)
                for dev in $DEVICES_TO_DISABLE_ON_LAN_CONNECT; do
                    [ -n "$dev" ] && device_off $dev
                done
                ;;

            *wireless|wifi)
                for dev in $DEVICES_TO_DISABLE_ON_WIFI_CONNECT; do
                    [ -n "$dev" ] && [ "$dev" != wifi ] && device_off $dev
                done
                ;;

            gsm)
                for dev in $DEVICES_TO_DISABLE_ON_WWAN_CONNECT; do
                    [ -n "$dev" ] && [ "$dev" != wwan ] && device_off $dev
                done
                ;;
        esac
        ;; # up

    down) # interface down, enable configured interfaces
        case $itype in
            *ethernet)
                for dev in $DEVICES_TO_ENABLE_ON_LAN_DISCONNECT; do
                    [ -n "$dev" ] && device_on $dev
                done
                ;;

            *wireless|wifi)
                for dev in $DEVICES_TO_ENABLE_ON_WIFI_DISCONNECT; do
                    [ -n "$dev" ] && [ "$dev" != wifi ] && device_on $dev
                done
                ;;

            gsm)
                for dev in $DEVICES_TO_ENABLE_ON_WWAN_DISCONNECT; do
                    [ -n "$dev" ] && [ "$dev" != wwan ] && device_on $dev
                done
                ;;
        esac
        ;; # down

esac

exit 0
