#!/bin/sh /etc/rc.common

source /lib/functions/uci-defaults.sh

START=70
STOP=12

USE_PROCD=1
PROG=/usr/sbin/dectmngr
LOG_PATH=/var/log/dectmngr
DB_PATH=/etc/dect
DCX81_UART_DT_ALIAS=/proc/device-tree/aliases/dcx81-uart

get_extension_shift() {
   local dect_exts

   get_dect_extension() {
       local ext=$1
       local type

       config_get type $ext type

       [ "$type" == "dect" ] && echo $ext
    }

    config_load "asterisk"

    dect_exts=$(config_foreach get_dect_extension "extension" |sort |head -n1)

    echo "${dect_exts#extension}"
}

# Ask dectmngr to exit nicely and wait for it to clean up, which is a slow process.
stop_and_wait_dectmngr() {
	dect_pid=$(pidof $PROG)
	[ -n "$dect_pid" ] && kill $dect_pid

	pidof $PROG > /dev/null 2>&1 && sleep 2 # wait for the process to stop gracefully
	while pidof $PROG > /dev/null 2>&1; do
		dect_pid=$(pidof $PROG)
		[ -n "$dect_pid" ] && kill -9 $dect_pid
		sleep 1
	done
}

has_dect() {
	[ -f "$DCX81_UART_DT_ALIAS" ]
}

get_dcx81_device() {
	readonly dcx81_uart_dt_node="/proc/device-tree/$(cat "$DCX81_UART_DT_ALIAS" 2>/dev/null)"
	[ -e "$dcx81_uart_dt_node" ] || return 1
	for tty_dt_node in /sys/class/tty/*/device/of_node; do
		if [ "$tty_dt_node" -ef "$dcx81_uart_dt_node" ]; then
			readonly uevent_file="${tty_dt_node%%/device/of_node}/uevent"
			local device_name_line
			device_name_line="$(grep '^DEVNAME=' "$uevent_file")" || return 1
			readonly device="/dev/${device_name_line##DEVNAME=}"
			[ -c "$device" ] || return 1
			printf "%s" "$(basename $device)"
			return 0
		fi
	done
	return 1
}

check_dcx81_firmware() {
	local dcx81_uart=$1
	local fw_link="/lib/firmware/dcx81_firmware"
	local fw_file

	[ -L "$fw_link" ] || return

	fw_file=$(readlink -f $fw_link)
	[ -f "$fw_file" ] || return

	# the symbolic link is not needed
	rm -f $fw_link

	eval $(/sbin/cmbs_tcx -comname "$dcx81_uart" -fw_version |grep DCX81_FW_Version)
	[ -n "$DCX81_FW_Version" ] || return

	if echo $(basename $fw_file) | grep -qi "$DCX81_FW_Version" ; then
		logger -t "$PROG" "DCX81 running expected $DCX81_FW_Version"
		return;
	fi

	logger -t "$PROG" "DCX81 firmware upgrading to $fw_file"
	/sbin/cmbs_tcx -comname "$dcx81_uart" -fwu "$fw_file" 2>&1 >/dev/null &

	echo -n "Updrading DCX81 firmware.." >/dev/console
	local wait_time=0
	while pidof cmbs_tcx >/dev/null && [ "$wait_time" -lt "200" ] ; do
		sleep 5
		wait_time=$(($wait_time + 5))
		echo -n "." >/dev/console
	done

	if pidof cmbs_tcx >/dev/null ; then
		killall -9 cmbs_tcx
		logger -t "$PROG" "DCX81 firmware upgrade timeout"
	else
		logger -t "$PROG" "DCX81 firmware upgrade done"
	fi
}

start_service() {
	local opt_ext=
	local rfpi=
	local model_id=
	local rxtun=

	if ! has_dect; then
		logger -t "$PROG" "Not starting because no DECT hardware is available."
		return 0
	fi

	local dcx81_uart_device
	if ! dcx81_uart_device="$(get_dcx81_device)"; then
		logger -t "$PROG" -p daemon.warning "Could not determine DCX81 UART device. Falling back to default ttyH0."
		dcx81_uart_device="ttyH0"
	fi

	check_dcx81_firmware $dcx81_uart_device

	opt_ext="-extensionShift $(get_extension_shift)"

	rfpi=$(db -q get hw.board.dect_rfpi)
	[ -n "$rfpi" -a ${#rfpi} -eq 14 ] && opt_ext="$opt_ext -rfpi $rfpi"

	model_id=$(db -q get hw.board.dect_model_id)
	[ -n "$model_id" -a ${#model_id} -eq 8 ] || {
		echo "Invalid hw.board.dect_model_id:$model_id. Set to 30.3B.06"
		model_id="30.3B.06"
	}
	opt_ext="$opt_ext -model $model_id"

	rxtun=$(db -q get hw.board.dect_rxtun)
	[ -n "$rxtun" -a ${#rxtun} -eq 2 ] && opt_ext="$opt_ext -rxtun $rxtun"

	config_load dect
	config_get log_dect_cmbs global log_dect_cmbs syslog
	config_get pcm_slot_start global pcm_slot_start
	config_get pcm_fsync global pcm_fsync

        [ -n "$pcm_fsync" ] && opt_ext="$opt_ext -sync $pcm_fsync"
        [ -n "$pcm_slot_start" ] && opt_ext="$opt_ext -slotsShift $pcm_slot_start"

	procd_open_instance

	case "$log_dect_cmbs" in
	none)
		echo "Starting dectmngr with cmbs logging disabled"
		procd_set_param command "$PROG" -comname "$dcx81_uart_device" $opt_ext
		rm -f $LOG_PATH/*
		;;
	file)
		echo "Starting dectmngr with cmbs logging enabled to file"
		procd_set_param command "$PROG" -comname "$dcx81_uart_device" -log $LOG_PATH/dect-cmbs.log $opt_ext
		;;
	*)
		echo "Starting dectmngr with cmbs logging enabled to syslog"
		procd_set_param command "$PROG" -comname "$dcx81_uart_device" -syslog $opt_ext
		rm -f $LOG_PATH/*
		;;
	esac

	procd_set_param respawn 6 2 3
	procd_set_param term_timeout 20
	procd_set_param triggers asterisk
	procd_close_instance
}

stop_service() {
	has_dect || return 0

	stop_and_wait_dectmngr
}

reload_service() {
	ubus call dect reload
}

service_triggers() {
	procd_add_config_trigger "config.change" "asterisk" /etc/init.d/dectmngr restart
	procd_add_config_trigger "config.change" "dect" /etc/init.d/dectmngr reload
}

boot() {
	[ ! -d $LOG_PATH ] && mkdir -p $LOG_PATH
	[ ! -d $DB_PATH ] && mkdir -p $DB_PATH
	start
}
