#!/bin/bash
#
# microapl Linkstation/Kuro Micro-Controller querry script
#
# Other files used are:
#   micro-evtd program
#
# Written by Bob Perry (2007-2009) lb-source@users.sourceforge.net
#

MICRO="micro-evtd -s"
MICRO_q="micro-evtd -q -s"

note_to_freq()
{
	local NOTEA="8E0B4705238211C108E0FFFF858C430F218710C30860FFFF"
	local NOTEB="FC047F083F421FA10FD007E8                        "
	local NOTEC="F06277463BA31DE00EEC0777E273706838681C340E16070C"
	local NOTED="D60A6A4A35251A9E0D4C06A6C8586429323D191E0C8C0647"
	local NOTEE="BE8C5EB22F5917B50BD805EC                        "
	local NOTEF="B39959492CC516620B2F0597A9D654752A3A151D0A8E0547"
	local NOTEG="9F704FB827DC13EE09F704FB963D4B1E25A612CD096804B4"

	if [ ${#1} -lt 2 ] || [ ${#1} -gt 3 ] ; then
	  echo -n "0000"
	fi

	local arg="$(echo -n $1 | tr 'a-z' 'A-Z')"

	local NOTE=$(echo $arg | sed 's/^\([A-Z]\).*/\1/')
	local NOTESTRING="$(eval echo \$NOTE$NOTE)"

	if [ "$(echo $arg | sed 's/^.\([A-Z]\).*/\1/')" = "M" ] ; then
	  local octave="$(($(echo $arg | sed 's/^..\([0-9]\).*/\1/') + 5))"
	else
	  local octave="$(($(echo $arg | sed 's/^.\([0-9]\).*/\1/') - 1))"
	fi

	# Build expression and pass it to sed, due to evaluation.
	expr="s/^.\{$(($octave*4))\}\(.\{4\}\).*/\1/"
	local result="$(echo $NOTESTRING | sed $expr)"
	if [ -n "$result" ] ; then
	  echo -n $result
	else
	  echo -n "0000"
	fi
}

parse()
{
	case $1 in
		boot_flash_ok)
			$MICRO_q 0007 ;;
		boot_start)
			$MICRO_q 0002 ;;
		boot_end)
			$MICRO_q 0003 ;;
		power_off)
			$MICRO_q 0006 ;;
		shutdown_wait)
			$MICRO_q 000C ;;
		shutdown_cancel)
			$MICRO_q 000D ;;
		skip_standby)
			if [ -f /boot/pending_standby ] ; then
			  PID=`pidof micro-evtd`
			  /bin/kill -SIGINT ${PID}
			  echo "Pending standby delay activated"
			else
			  echo "Not supported function"
			fi ;;
		delay_standby)
			if [ -f /boot/pending_standby ] ; then
			  PID=`pidof micro-evtd`
			  COUNT=1
			  ## Delay amount?
			  if [ "$2" != "" ] ; then
			    ## We only do 5 mins intervals
			    ((COUNT=($2+4)/5))
			  fi
			  LOOP=0
			  DELAY=0
			  while [ ${LOOP} -lt ${COUNT} ] ; do
			    ((DELAY +=5))
			    ((LOOP ++))
			    /bin/kill -SIGCONT ${PID}
			    LC=0 ; while [ ${LC} -lt 50 ] ;do ((LC ++)) ; done
			  done
			  echo "Standby delayed by additional ${DELAY} minutes"
			else
			  echo "Not supported function"
			fi ;;
		standby_remaining)
			if [ -f /boot/pending_standby ] ; then
			  PID=`pidof micro-evtd`
			  /bin/kill -SIGHUP ${PID}
			else
			  echo "Not supported function"
			fi ;;
		standby)
			if [ -f /boot/pending_standby ] ; then
			  micro-evtd -q -s 02520100
		      mv -f /boot/pending_standby /boot/standby
			  reboot
			else
			  echo "Not supported function"
			fi ;;
		reboot)
			$MICRO_q 000E ;;
		system_get_mode)
			$MICRO 8034 ;;
		system_set_watchdog)
			if [ "$2" == "" ] ; then
			  TEMP=`$MICRO 8035`
			  TEMP=`expr 255 - ${TEMP}`
			  echo "#[microapl.system_set_watchdog]"
			  if [ ${TEMP} -lt 255 ] ; then
			    echo "watchdog=${TEMP}[sec]"
			  else
			    echo "watchdog=off"
			  fi
			else
			  if [ "$2" = "off" ] ; then
			    $MICRO_q 013500
			  else
			    TEMP=`expr 255 - $2`
			    TEMP=`printf "%02d", ${TEMP}`
			    $MICRO_q 0135${TEMP}
			  fi
			fi ;;
		temp_get)
			TEMP=`$MICRO 8037`
			echo "#[microapl.temp_get]"
			echo "temp="${TEMP}"[C-degs]" ;;
		fan_set_speed)
			if [ "$2" == "" ] ; then
			  echo "#[microapl.fan_set_speed]"
			  echo -n "fan_set_speed="
			  case `$MICRO 8033` in
			    0) echo "stop" ;;
				1) echo "slow" ;;
				2) echo "fast" ;;
				3) echo "full" ;;
				*) echo "unknown" ;;
			  esac
			else
			  case $2 in
			    stop) $MICRO_q 013300 ;;
			    slow) $MICRO_q 013301 ;;
			    fast) $MICRO_q 013302 ;;
			    full) $MICRO_q 013303 ;;
			    *) echo "fan_set_speed: invalid parameter ($2)"
			  esac
			fi ;;
		fan_get_speed)
			TEMP=`$MICRO 8038`
			SPEED=`expr ${TEMP} "*" 30`
			echo "#[microapl.fan_get_speed]"
			echo "fan_rpm="$SPEED"rpm" ;;
		bz_on)
			case $2 in
			  stop)    $MICRO_q 013000 ;;
			  boot)    $MICRO_q 013001 ;;
			  button)  $MICRO_q 013002 ;;
			  on)      $MICRO_q 013003 ;;
			  on3off3) $MICRO_q 013004 ;;
			  on5off3) $MICRO_q 013010 ;;
			  finepix) $MICRO_q 013020 ;;
			  *)       $MICRO_q 013000 ;;
			esac ;;
		bz_set_freq)
			if [ "$2" == "" ] ; then
			  echo "#[microapl.bz_set_freq]"
			  echo "bz_set_freq="`$MICRO 8053`
			else
			  TEMP=`expr $2 % 255`
			  TEMP2=`expr $2 - 255`
			  if [ ${TEMP2} -lt 0 ] ; then
			    TEMP2="00"
			  else
			    TEMP2="FF"
			  fi
			  TEMP=`printf "%02X" ${TEMP}`
			  $MICRO_q 0253${TEMP}${TEMP2}
			fi ;;
		bz_imhere)
			if [ "$2" == "" ] ; then
			  echo "please specify tempo and note(s)"
			else
			  TIME="$(($2 / 1000)).$(printf '%03d' $(($2 % 1000)))"
			  STATE=0
			  shift
			  shift
			  parse led_set_cpu_mcon 15
			  $MICRO_q 0253$(note_to_freq $1)
			  shift
			  parse bz_on on
			  for i in $@ ; do
			    $MICRO_q 0253$(note_to_freq $i)
			    if [ $STATE -eq 0 ] ; then
			      parse led_set_on_off 15
			      STATE=1
			    else
			      parse led_set_on_off 0
			      STATE=0
			    fi
			    sleep "$TIME"
			  done
			  parse bz_on off
			  parse led_set_cpu_mcon 0
			fi ;;
		bz_melody)
			if [ "$2" == "" ] ; then
			  echo "please specify tempo and note(s)"
			else
			  TIME="$(($2 / 1000)).$(printf '%03d' $(($2 % 1000)))"
			  shift
			  shift
			  $MICRO_q 0253$(note_to_freq $1)
			  shift
			  parse bz_on on
			  for i in $@ ; do
			    $MICRO_q 0253$(note_to_freq $i)
			    sleep "$TIME"
			  done
			  parse bz_on off
			fi ;;
		int_get_switch_status)
			echo "#[microapl.int_get_switch_status]"
			echo -n "int="
			case `$MICRO 8036` in
			  1) echo "power_sw" ;;
			  8) echo "init_sw_front" ;;
			  *) echo "unknown" ;;
			esac
			;;
		led_set_bright)
			if [ "$2" == "" ] ; then
			  TEMP=`$MICRO 803A`
			  TEMP="$((${TEMP} & 0xF))"
			  case "${TEMP}" in
			    0)  TEMP=0 ;;
			    1)  TEMP=10 ;;
			    2)  TEMP=15 ;;
			    3)  TEMP=20 ;;
			    4)  TEMP=25 ;;
			    5)  TEMP=30 ;;
			    6)  TEMP=40 ;;
			    7)  TEMP=45 ;;
			    8)  TEMP=50 ;;
			    9)  TEMP=55 ;;
			    10) TEMP=60 ;;
			    11) TEMP=65 ;;
			    12) TEMP=70 ;;
			    13) TEMP=80 ;;
			    14) TEMP=90 ;;
			    15) TEMP=100 ;;
			  esac
			  echo "#[microapl.led_set_bright]"
			  echo "led_set_bright=${TEMP}%"
			else
			  case "$2" in
			    0)   TEMP=0 ;;
			    10)  TEMP=1 ;;
			    15)  TEMP=2 ;;
			    20)  TEMP=3 ;;
			    25)  TEMP=4 ;;
			    30)  TEMP=5 ;;
			    40)  TEMP=6 ;;
			    45)  TEMP=7 ;;
			    50)  TEMP=8 ;;
			    55)  TEMP=9 ;;
			    60)  TEMP=10 ;;
			    65)  TEMP=11 ;;
			    70)  TEMP=12 ;;
			    80)  TEMP=13 ;;
			    90)  TEMP=14 ;;
			    100) TEMP=15 ;;
			    off) TEMP=0 ;;
			    *) echo "led_set_bright: invalid parameter ($2)" ;;
			  esac
			  TEMP="$(printf "%02X" ${TEMP})"
			  $MICRO_q 013A${TEMP}
			fi ;;
		led_set_cpu_mcon | \
		led_set_on_off |   \
		led_set_blink |    \
		led_set_brink)
			case $1 in
			  led_set_cpu_mcon) COMMAND=50 ; SET="cpu" ; UNSET="mcon" ;;
			  led_set_on_off)   COMMAND=51 ; SET="on" ;  UNSET="off" ;;
			  led_set_blink | \
			  led_set_brink)    COMMAND=52 ; SET="on";   UNSET="off" ;;
			esac
			if [ "$2" == "" ] ; then
			  echo "#[microapl.$1]"
			  TEMP=`$MICRO 80${COMMAND}`
			  # extract first element
			  TEMP="${TEMP%% *}"
			  if [ "$((${TEMP} & 1 ))" -gt 0 ] ; then echo "led_power=${SET}" ; else echo "led_power=${UNSET}" ; fi
			  if [ "$((${TEMP} & 2 ))" -gt 0 ] ; then echo "led_info=${SET}" ; else echo "led_info=${UNSET}" ; fi
			  if [ "$((${TEMP} & 4 ))" -gt 0 ] ; then echo "led_diag=${SET}" ; else echo "led_diag=${UNSET}" ; fi
			  if [ "$((${TEMP} & 8 ))" -gt 0 ] ; then echo "led_link=${SET}" ; else echo "led_link=${UNSET}" ; fi
			else
			  shift
			  TEMP=0
			  for i in $@ ; do
			    case $i in
			      power) TEMP=$(($TEMP | 1)) ;;
			      info)  TEMP=$(($TEMP | 2)) ;;
			      diag)  TEMP=$(($TEMP | 4)) ;;
			      link)  TEMP=$(($TEMP | 8)) ;;
			      off)   TEMP=0 ;;
			      *)     TEMP="$i" ;;
			    esac
			  done
			  TEMP="$(printf "%02X" $TEMP)"
			  $MICRO_q 02${COMMAND}${TEMP}00
			fi ;;
		led_set_code_error)
			if [ "$2" == "" ] ; then
			  TEMP=`$MICRO 8054`
			  TEMP="${TEMP##* }"
			  echo "#[microapl.led_set_code_error]"
			  echo -n "led_code_error="
			  case "${TEMP}" in
			    00) echo "MPU ERROR" ;;
			    01) echo "DRAM DATA LINE ERROR" ;;
			    02) echo "DRAM ADDRESS LINE ERROR" ;;
			    03) echo "RTC CHIP ERROR" ;;
			    04) echo "FLASH ERROR" ;;
			    16) echo "UPS POWER LOSS" ;;
			    17) echo "FAN ERROR: LOW SPEED OR FAN STOPPED" ;;
			    18) echo "COOLING ERROR" ;;
			    21) echo "DISK ERROR" ;;
			    22) echo "NO HDD DETECTED" ;;
			    23) echo "RTC CHIP NOT DETECTED" ;;
			    33) echo "PHY CHIP NOT DETECTED" ;;
			    34) echo "MOUNT ERROR" ;;
			    *)  echo "UNDEFINED ERROR: 0x${TEMP}" ;;
			  esac
			else
			  TEMP=`$MICRO 8054`
			  TEMP="$(printf "%02X" ${TEMP%% *})"
			  ARG="$(printf "%02d" $2)"
			  $MICRO_q 0254${TEMP}${ARG}
			fi ;;
		led_set_code_information)
			if [ "$2" == "" ] ; then
			  TEMP=`$MICRO 8054`
			  TEMP="${TEMP%% *}"
			  TEMP="$(printf '%02X' ${TEMP})"
			  echo "#[microapl.led_set_code_information]"
			  echo -n "led_code_information="
			  case ${TEMP} in
			    15) echo "5MINS TO STANDBY" ;;
			    16) echo "OVERHEAT DETECTED" ;;
			    32) echo "HDD FORMATTING" ;;
			    33) echo "HDD CHECKING" ;;
			    34) echo "RECOVERING HDD" ;;
			    35) echo "INITIALISING SYSTEM" ;;
			    36) echo "FIRMWARE UPDATE IN PROGRESS" ;;
			    37) echo "WEB INITIALISING" ;;
			    38) echo "USB CHECKING" ;;
			    39) echo "USB FORMATTING" ;;
			    *)  echo "UNDEFINED: 0x${TEMP}" ;;
			  esac
			else
			  TEMP=`$MICRO 8054`
			  TEMP="$(printf "%02X" ${TEMP##* })"
			  ARG="$(printf "%02d" $2)"
			  $MICRO_q 0254${ARG}${TEMP}
			fi ;;
		mcon_get_status)
			echo "#[microapl.mcon_get_status]"
			echo -n "mcon_status="
			if [ `$MICRO 803C` == "32" ] ; then
			  echo "on"
			else
			  echo "off"
			fi
			;;
		mcon_get_version)
			echo "#[microapl.mcon_get_version]"
			echo -n "mcon_version="
			TEMP=`$MICRO 8083`
			if [ "${TEMP}" == -1 ] ; then
			  echo "(error while getting version)"
			else
			  for i in ${TEMP} ; do
			    echo -ne "\0$(printf '%o' $i)"
			  done
			  echo
			fi
			;;
		hdd_set_power)
			if [ "$2" == "" ] ; then
			  echo "#[microapl.hdd_set_power]"
			  case `$MICRO 803B` in
			    0) echo -e "hdd12_power=off\nhdd34_power=off" ;;
			    1) echo -e "hdd12_power=on\nhdd34_power=off" ;;
			    2) echo -e "hdd12_power=off\nhdd34_power=on" ;;
			  esac
			else
			  TEMP=`printf "0x%02X" $2`
			  $MICRO_q 013B${TEMP}
			fi
            ;;
		*)
			echo "invalid command ($1)"
			;;
	esac
}

case $1 in
-a)
	shift
	parse $@ ;;
-v)	echo "microapl version 1.1" ;;
*)
	echo "option: boot_start"
	echo "boot_end"
	echo "power_off"
	echo "shutdown_wait"
	echo "shutdown_cancel"
	echo "skip_standby"
	echo "delay_standby [arg]"
	echo "standby_remaining"
	echo "standby"
	echo "reboot"
	echo "temp_get"
	echo "fan_set_speed [arg]"
	echo "fan_get_speed"
	echo "bz_on [arg]"
	echo "bz_set_freq [arg]"
	echo "bz_melody tempo note ..."
	echo "bz_imhere tempo note ..."
	echo "int_get_switch_status [arg]"
	echo "led_set_bright [arg]"
	echo "led_set_cpu_mcon [arg]"
	echo "led_set_on_off [arg]"
	echo "led_set_blink [arg]"
	echo "led_set_code_error [arg]"
	echo "led_set_code_information [arg]"
	echo "led_set_cpu_mcon [arg]"
	echo "mcon_get_status"
	echo "hdd_set_power [arg]"
	echo "mcon_get_version"
	;;
esac

exit 0
