#!/bin/bash
#
# * List of changes (generated via git log --oneline --decorate --pretty="format:%<(35)%ad %<(25)%an %s" ./recipes-core/init-ifupdown/files/init)
#
# Timestamp                           Author                    Description
# --
# Wed May 13 12:46:57 2020 +0200      Steven Dorigotti          BSP-1938 Wifi autostart may fail (depending on boot sequence)
# Mon May 11 17:38:43 2020 +0200      Steven Dorigotti          BSP-1926 Fix DHCP client boot sequence
# Fri May 8 17:11:02 2020 +0200       Steven Dorigotti          BSP-1926 ETOP707T US05 support (hwcode 146)
# Mon Oct 29 09:12:50 2018 +0100      Steven Dorigotti          BSP-1145 DHCP Server fails if interface is not up; s/interfaces/id
# Tue Oct 23 00:09:42 2018 +0200      Steven Dorigotti          BSP-1293 Fix syntax error in last commit of networking script
# Mon Oct 22 14:30:03 2018 +0200      Steven Dorigotti          BSP-1293 Custom DNS configuration ignored after reboot while modem is running - Case ID: 201806611
# Wed Sep 12 19:04:26 2018 +0200      Steven Dorigotti          BSP-1145 DHCP Server (based on Busybox udhcpd)
# Mon Sep 3 16:12:51 2018 +0200       Steven Dorigotti          BSP-1247 Networking script no longer resets modem (now done internally by script)
# Mon Sep 3 13:33:19 2018 +0200       Steven Dorigotti          BSP-1247 Always reset modem upon start (not only upon boot)
# Mon Aug 13 10:13:04 2018 +0200      Steven Dorigotti          BSP-1144 Fix wifi preserve syntax and s/autostartNics/autostartInterfaces
# Sun Jul 15 00:50:45 2018 +0200      Steven Dorigotti          BSP-983 Migrate WiFi logic from System Settings to EPAD
# Tue Jan 2 14:52:37 2018 +0100       Steven Dorigotti          BSP-928 PLCM09: Handle Mobile Network Authentication
# Mon Dec 11 10:35:20 2017 +0100      Steven Dorigotti          BSP-929 PLCM09: Don't start mobile networking (from init) if controlled externally
# Mon Oct 16 11:30:13 2017 +0200      Steven Dorigotti          BSP-846 UN6x: Allow edit of service options without enable and decouple enable/start
# Wed Jul 5 09:26:18 2017 +0200       Steven Dorigotti          BSP-726 UN6x: networking init uses modem script
# Fri Jun 30 14:47:31 2017 +0200      Steven Dorigotti          BSP-726 UN6x: Increase PLCM09 baud rate to 3000000 and udev now starts before networking (for plugin devices)
# Thu Jun 15 16:13:48 2017 +0200      Steven Dorigotti          BSP-726 UN6x: Force PLCM09 reset upon boot
# Wed Jun 14 17:13:48 2017 +0200      Steven Dorigotti          BSP-726 UN6x: PLCM09 baud rate set to 921600
# Thu Jun 8 23:49:09 2017 +0200       Steven Dorigotti          BSP-726 UN6x: Basic PLCM09 plugin support and connectivity (hardcoded:vodafone,no pin,com2)
# Fri Mar 3 23:31:44 2017 +0100       Steven Dorigotti          BSP-566 UN6x: Add -f when pulling down bridge/wifi for extra reliability
# Fri Mar 3 18:58:08 2017 +0100       Steven Dorigotti          BSP-566 UN6x: export PATH in networking script since EPAD doesn't set it and children need it
# Fri Feb 24 13:43:17 2017 +0100      Steven Dorigotti          BSP-600 UN6x: Only ifplugd should manage ethernet interfaces
# Thu Feb 23 01:48:51 2017 +0100      Steven Dorigotti          BSP-566 UN6x: Static configuration of unplugged interfaces not visible in System Settings
# Tue Jan 31 21:24:35 2017 +0100      Steven Dorigotti          BSP-437 UN6x: Support bridging of networking interfaces
# Wed Jan 18 01:48:48 2017 +0100      Steven Dorigotti          BSP-437 UN6x: Experimental/hard-coded bridge
# Thu Jul 14 19:13:47 2016 +0200      Steven Dorigotti          BSP-262 BSP: supporto config. WiFi
# Wed Jun 29 14:05:56 2016 +0200      Steven Dorigotti          BSP-262 BSP: supporto config. WiFi
# Thu Jan 21 10:49:29 2016 +0100      Nicol<C3><B2> Ongaro      Revert "BSP-10113 bring up can interfaces if any", interface mangement is left to protocol software
# Mon Jan 11 11:59:37 2016 +0100      Nicol<C3><B2> Ongaro      BSP-10113 bring up can interfaces if any
# Tue Oct 20 22:25:06 2015 +0200      Steven Dorigotti          BSP-9540 DHCP discovery at boot when ethernet cable unplugged
# Mon Oct 19 18:57:28 2015 +0200      Nicol<C3><B2> Ongaro      Revert ifup changes from ifupdown start script
# Fri Oct 2 10:09:41 2015 +0200       Nicol<C3><B2> Ongaro      BSP-9540 fix blocking DHCP discovery
# Mon Apr 13 00:19:36 2015 +0200      Steven Dorigotti          jmcloud BSP-90 init-ifupdown: /etc/network/interfaces is now initially generated by /etc/init.d/networking based on available interfaces
# Fri Jan 16 11:52:33 2015 +0100      Steven Dorigotti          init-ifupdown: add -f to ifdown to avoid errors upon restart
# Fri Jan 16 11:51:58 2015 +0100      Steven Dorigotti          init-ifupdown: imported init

### BEGIN INIT INFO
# Provides:          networking
# Required-Start:    mountvirtfs $local_fs
# Required-Stop:     $local_fs
# Should-Start:      ifupdown
# Should-Stop:       ifupdown
# Default-Start:     S
# Default-Stop:      0 6
# Short-Description: Raise network interfaces.
### END INIT INFO

export PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
INTERFACESCONF="/etc/network/interfaces"
PPCMD="`cat /proc/$PPID/comm`"
MODEM_PREV_STATE="0"
SKIPMODEM=0

[ -x /sbin/ifup ] || exit 0

. /etc/exorint.funcs

check_network_file_systems() {
    [ -e /proc/mounts ] || return 0

    if [ -e /etc/iscsi/iscsi.initramfs ]; then
	echo "not deconfiguring network interfaces: iSCSI root is mounted."
	exit 0
    fi

    exec 9<&0 < /proc/mounts
    while read DEV MTPT FSTYPE REST; do
	case $DEV in
	/dev/nbd*|/dev/nd[a-z]*|/dev/etherd/e*)
	    echo "not deconfiguring network interfaces: network devices still mounted."
	    exit 0
	    ;;
	esac
	case $FSTYPE in
	nfs|nfs4|smbfs|ncp|ncpfs|cifs|coda|ocfs2|gfs|pvfs|pvfs2|fuse.httpfs|fuse.curlftpfs)
	    echo "not deconfiguring network interfaces: network file systems still mounted."
	    exit 0
	    ;;
	esac
    done
    exec 0<&9 9<&-
}

# Generate DHCP network configuration based on actual detected interfaces
# (only if file does not already exist)
gen_network_interfaces() {
	[ -r "${INTERFACESCONF}" ] && return 0
	INTERFACESCONFTMP="${INTERFACESCONF}".tmp

	{
		echo "# Generated by /etc/init.d/networking"
		echo "auto lo"
		echo "iface lo inet loopback"
		for interface in /sys/class/net/eth*; do
			IFACE=`basename $interface`;
			echo auto $IFACE;
			echo iface $IFACE inet dhcp
		done

	} > "${INTERFACESCONFTMP}"

    mv "${INTERFACESCONFTMP}" "${INTERFACESCONF}"
}

check_network_swap() {
    [ -e /proc/swaps ] || return 0

    exec 9<&0 < /proc/swaps
    while read DEV MTPT FSTYPE REST; do
	case $DEV in
	/dev/nbd*|/dev/nd[a-z]*|/dev/etherd/e*)
	    echo "not deconfiguring network interfaces: network swap still mounted."
	    exit 0
	    ;;
	esac
    done
    exec 0<&9 9<&-
}

#
# Control interfaces which are not managed by ifplugd
#

start_other() {
	# bridge
	grep -q "^auto br0" $INTERFACESCONF	&& ifup br0 &

	# wifi
	if [ "${PPCMD}" = "rc" ]; then
		# EPAD might not be up yet (and direct servicemanager call may time out..) force a test
		dbus-send --print-reply --system --dest=com.exor.EPAD "/" com.exor.EPAD.getSystemParameter string:"test"
		# force interfaces update in case any are missing (e.g. USB ethernet)
		dbus-send --print-reply --system --dest=com.exor.EPAD "/NetworkManager" com.exor.EPAD.NetworkManager.updateInterfaces
		for wiface in `sys_params network/wifi/autostartInterfaces 2>/dev/null`; do
			RC=$(dbus-send --print-reply=literal --system --dest=com.exor.EPAD "/ServiceManager" com.exor.EPAD.ServiceManager.command \
					string:"wifi" string:"start" string:"{ \"id\" : \"$wiface\" }" | awk '{ printf $2 }')
			[ "${RC}" = "0" ] || logger "WARNING wifi start returned: ${RC}!"
		done
	else
		RC=$(dbus-send --print-reply=literal --system --dest=com.exor.EPAD "/ServiceManager" com.exor.EPAD.ServiceManager.command \
				string:"wifi" string:"start" string:"{ \"preserve\" : true }" | awk '{ printf $2 }')
		[ "${RC}" = "0" ] || logger "WARNING wifi start returned: ${RC}!"
	fi
	# [modem]
        if [ ${SKIPMODEM} -eq 0 ]; then
	        if [ "${PPCMD}" = "rc" ]; then
		        if [ "$(/usr/bin/sys_params services/mobile/autostart 2>/dev/null)" = "true" ]; then
			        if dbus-send --print-reply=literal --system --dest=com.exor.EPAD "/ServiceManager" \
				       com.exor.EPAD.ServiceManager.controlled string:"mobile" | grep -q "boolean true"; then
				       echo "Mobile Service controlled externally - doing nothing"
			        else
				       /usr/bin/modem start &
			        fi
		        fi
	        else
		        if [ "$(/usr/bin/sys_params services/mobile/enabled 2>/dev/null)" = "true" ]; then
			        /usr/bin/modem start
		        fi
	        fi
	        /usr/bin/sys_params -w services/mobile/enabled "" 2>/dev/null # delete temporary key
        else
                logger "Skip modem start"
        fi
}

stop_other() {
	# modem
        if [ ${SKIPMODEM} -eq 0 ]; then
	        /usr/bin/modem stop
        else
                logger "Skip modem stop"
        fi
	# wifi
	dbus-send --print-reply --system --dest=com.exor.EPAD "/ServiceManager" com.exor.EPAD.ServiceManager.command \
			string:"wifi" string:"stop" string:"{ \"preserve\" : true }" > /dev/null
	# bridge
	grep -q "^auto br0" $INTERFACESCONF	&& ifdown -f br0
	# loopback
	ifconfig lo down
}

do_start() {
	echo -n "Configuring network interfaces... "
	sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1
	gen_network_interfaces

	# loopback
	ifconfig lo up  # some services need this (e.g. JMUConfig)

	# hardware switch - managed only for ETOP707T
	if [ "${PPCMD}" = "rc" -a "$(exorint_hwcode)" = "146" ]; then
		ifconfig eth1 up
		ifconfig SE01 up
		ifconfig CE01 up
		ifconfig CE02 up
		ifconfig CE03 up
	fi

	/etc/init.d/ifplugd start

	# refresh custom DNS info (otherwise updated only upon ifup/ifdown)
	/sbin/resolvconf -u

	start_other &
}

do_stop() {
	#check_network_file_systems
	#check_network_swap

	echo -n "Deconfiguring network interfaces... "

	/etc/init.d/ifplugd stop
	stop_other

	# give some time for interfaces to be pulled down
	# Note: this could be improved/removed in the future by making EPAD calls
	# synchronous/multiclient (e.g. startDetached calls in impl/generic/services/wifi.cpp)
	sleep 3
}

for opt in "$@"
do
       case "$opt" in
          --modemskip)
                 SKIPMODEM=1
                 ;;
       esac
done

case "$1" in
start)
    do_start
	echo "done."
	;;

stop)
    do_stop
	echo "done."
	;;

force-reload|restart)
	echo "Running $0 $1 is deprecated because it may not enable again some interfaces"

	do_stop
	do_start

	echo "done."
	;;

*)
	echo "Usage: /etc/init.d/networking {start|stop}"
	exit 1
	;;
esac

exit 0
