#!/bin/bash
##############################################################################
#
#  Copyright (c) 2005, Doremi Labs, Inc.
#    All rights reserved.
#
#  Redistribution in source or binary forms, with or without
#  modification, are NOT permitted.
#
#    Doremi Labs, Inc.
#    1020 Chestnut St.
#    Burbank, CA 91506
#    Tel : (818) 562 1101
#    Fax : (818) 562 1109
#
##############################################################################

#
# Remount all read-only filesystem to read-write
#
set_readonly_fs_to_readwrite()
{
	mount -o rw,remount /
	mount -o rw,remount /boot
}

#
# Remount all orignal read-only to read-only
#
restore_readonly_fs()
{
	mount -o ro,remount /
	mount -o ro,remount /boot
}

MOTHERBOARD_MODEL_D945GTP=1
MOTHERBOARD_MODEL_SE7221x=2
MOTHERBOARD_MODEL_S3000AH=3
MOTHERBOARD_MODEL_S3210=4
MOTHERBOARD_MODEL_S3010=5
MOTHERBOARD_MODEL_PDSM4=6
MOTHERBOARD_MODEL_X7SB4=7
MOTHERBOARD_MODEL_X7SLA=8
MOTHERBOARD_MODEL_X7SPA=9
MOTHERBOARD_MODEL_FUSION=10

HOTPLUG_SYNC_FILE="/tmp/dolphin.dev.done"
HOTPLUG_LOG_FILE="/doremi/log/hotplug.log"

#
# Get motherboard model
#
motherboard_model()
{
	local platform=""
	
	if [ -e /etc/platform ]; then
		platform=$(cat /etc/platform)
	fi
	if [ "$platform" == "ims" ]; then
		model="fusion"
	elif [ -x /usr/sbin/dmidecode ] ; then
		model="`/usr/sbin/dmidecode | grep -2 'Base Board Information' | tail -1 | cut -f2 -d':' | tr -d [:space:] | tr -d [:alpha:]`"
	else
		model=""
	fi
	# Convert string to an enum-style value
	case "$model" in
		945*)
			return $MOTHERBOARD_MODEL_D945GTP	
			;;
		7221*)
			return $MOTHERBOARD_MODEL_SE7221x
			;;
		3000*)
			return $MOTHERBOARD_MODEL_S3000AH
			;;
		3010*)
			return $MOTHERBOARD_MODEL_S3010
			;;
		3210*)
			return $MOTHERBOARD_MODEL_S3210
			;;
		fusion)
			return $MOTHERBOARD_MODEL_FUSION
			;;
		*)
			# One last check for SE7221BK
			if [ -x /usr/sbin/dmidecode ] ; then
				/usr/sbin/dmidecode | grep SE7221BK > /dev/null
				if [ $? -eq 0 ] ; then
					return $MOTHERBOARD_MODEL_SE7221x
				fi
			fi
			;;
	esac
	if [ -x /usr/sbin/dmidecode ] ; then
		model="`/usr/sbin/dmidecode | grep -2 'Base Board Information' | tail -1 | cut -f2 -d':' | tr -d [:space:]`"
	else
		model=""
	fi
	# Convert string to an enum-style value
	case "$model" in
		PDSM4*)
			return $MOTHERBOARD_MODEL_PDSM4
			;;
		X7SB4*)
			return $MOTHERBOARD_MODEL_X7SB4
			;;
		X7SLA*)
			return $MOTHERBOARD_MODEL_X7SLA
			;;
		X7SP*)
			return $MOTHERBOARD_MODEL_X7SPA
			;;
		*)
			;;
	esac
	return 0
}

#
# Mkdir Doremi app. directories
#
build_doremi_hier()
{
	test -d /doremi				||	mkdir -p /doremi
	test -d /doremi/etc				||	mkdir -p /doremi/etc
	test -d /doremi/log				||	mkdir -p /doremi/log
	test -d /doremi/tmp				||	mkdir -p /doremi/tmp
	test -d /doremi/bin				||	mkdir -p /doremi/bin
	test -d /doremi/kdms			||	mkdir -p /doremi/kdms
	test -d /doremi/dlms			||	mkdir -p /doremi/dlms
	test -d /doremi/opt/schedulerd  	||	mkdir -p /doremi/opt/schedulerd
	test -d /doremi/opt/drmplaylistd	||	mkdir -p /doremi/opt/drmplaylistd
	test -d /doremi/opt/cinelister		||	mkdir -p /doremi/opt/cinelister
	test -d /doremi/opt/dbs			||	mkdir -p /doremi/opt/dbs
	test -d /var/lock/subsys			||	mkdir -p /var/lock/subsys
	test -d /tmp/snmp				||      mkdir -p /tmp/snmp

	test -d /data					||	mkdir -p /data
	test -d /data/incoming/gui		||	mkdir -p /data/incoming/gui
	test -d /data/assets			||	mkdir -p /data/assets
	test -d /data/maps				||	mkdir -p /data/maps
	test -d /data/tmp				||	mkdir -p /data/tmp
	test -d /data/playlists			||	mkdir -p /data/playlists
	test -d /data/repository			||	mkdir -p /data/repository
	test -d /data/repository/primary	||	mkdir -p /data/repository/primary
	test -d /data/repository/secondary	||	mkdir -p /data/repository/secondary
	
	test -d /mnt/autofs				||	mkdir -p /mnt/autofs
	test -L /media/autofs			||	ln -sf /mnt/autofs  /media/autofs

	test -e /data/kdms				||	ln -sf /doremi/kdms /data/kdms
	test -e /data/dlms				||	ln -sf /doremi/dlms /data/dlms

	test -f /doremi/etc/language		&&	(chown root:admin /doremi/etc/language && \
								chmod 0664 /doremi/etc/language)
}

#
#  ver2num()
#	Convert Doremi version number to a long int value. 
# 
ver2num()
{
	echo "$1" | awk -F '[^0-9]+' '{print $1*256*65536+$2*65536+$3*256+$4}'
}

#
#  pkg_check_dcp2000_release_version()
#	Check if the DCP2000 software release version is >= 0.5.2-25
#	INPUT : release version ($1)
#	OUTPUT: 1 = Release is >= 0.5.2-25
#		0 = Release is <  0.5.2-25
#
pkg_check_dcp2000_release_version()
{
	softnum=`ver2num "$1"`	
	softmin=`ver2num "0.5.2-25"`
	if [ $softnum -gt $softmin ] ; then
		return 1
	fi
	return 0 
}

#
#  pkg_is_dcp2000_release()
#	Check if the package is a DCP2000 software release.
#	INPUT : filename.PKG ($1)
#	OUTPUT: 1 = DCP2000 software release
#		0 = other package
#		pkg_dcp2000_release= "VERSION"
#
pkg_dcp2000_release=
pkg_is_dcp2000_release()
{
	files=$( gunzip -c $1 | tar -tf - ) 
	if [ "$files" == "" ] ; then
		return 0
	fi
	for file in $files ; do
		case $file in
			dcp2000_install-*.sh)
				pkg_dcp2000_release=$( echo $file | sed -e 's/^dcp2000_install-//' | sed -e 's/.sh$//' )
				return 1
				;;
			dcp2000-install-*.sh)
				pkg_dcp2000_release=$( echo $file | sed -e 's/^dcp2000-install-//' | sed -e 's/.sh$//' )
				return 1
				;;
			*)	;;
		esac
	done
	return 0
}

#
#  dolphin_type()
#	Returns whether the board matches the provided input type
#	INPUT :
#		expected board type:
#			dolphin_revB = dolphin revB
#			dolphin_dci = dolphin dci 1.0
#			dolphin_ltd = dolphin dci 1.2 low cap
#			dolphin_fullcap = dolphin dci 1.2 full cap
#			dolphin = dolphin revB or dolphin dci 1.0 boards
#			clarity = clarity board
#			certainty = certainty board
#			fusion = fusion board
#	OUTPUT:
#		0 = board matches the provided type
#		1 = board does not match the provided type
#
board_type()
{
	if [ $# == 1 ]; then
		local type=$1
	else
# compatibility with 2.0 branch
		local type=$2
	fi
	
	if [ ! -e /proc/dolphin0 ] || [ -z "$type" ]; then
		return 1
	fi
    
	local mcore_cap=$(grep MCORE_CAP /proc/dolphin0 | awk '{print $2}')
	if [ -z "$mcore_cap" ]; then
		return 1
	fi
	mcore_cap=0x$mcore_cap
	
	local fpga_cap=$(grep FPGA_CAP /proc/dolphin0 | awk '{print $2}')
	if [ -z "$fpga_cap" ]; then
		return 1
	fi
	fpga_cap=0x$fpga_cap
	
	if [ $(( ($fpga_cap >> 29) & 1 )) -eq 1 ]; then
		if [ $type == "fusion" ]; then
			return 0
		else
			return 1
		fi
	elif [ $(( ($fpga_cap >> 23) & 1 )) -eq 1 ]; then
		if [ $type == "certainty" ]; then
			return 0
		else
			return 1
		fi
	elif [ $(( ($fpga_cap >> 14) & 1 )) -eq 1 ]; then
		if [ $type == "clarity" ]; then
			return 0
		else
			return 1
		fi
	elif [ $(( ($mcore_cap >> 29) & 1 )) -eq 1 ]; then
		if [ $type == "dolphin_ltd" ]; then
			return 0
		else
			return 1
		fi
	elif [ $(( ($mcore_cap >> 30) & 1 )) -eq 1 ]; then
		if [ $type == "dolphin_fullcap" ]; then
			return 0
		else
			return 1
		fi
	elif [ $(( ($fpga_cap >> 1) & 1 )) -eq 1 ]; then
		if [ $type == "dolphin" ] || [ $type == "dolphin_dci" ]; then
			return 0
		else
			return 1
		fi
	else
		if [ $type == "dolphin" ] || [ $type == "dolphin_revB" ]; then
			return 0
		else
			return 1
		fi
	fi
}

#
#  projector_type()
#	Returns whether the board matches the provided input type
#	INPUT :
#		expected board type:
#			barco = barco serie 2 projector
#			christie = christie serie 2 projector
#			nec = nec projector
#			sony = sony 2D / 3D setup
#	OUTPUT:
#		0 = board matches the provided type
#		1 = board does not match the provided type
#
projector_type()
{
	local expected=$1
	
#    if [ ! -e /proc/dolphin0 ] || [ -z "$type" ]; then
#            return 1
#    fi
	
	local type=`/doremi/sbin/sbcsetup.out -a --get-projector-type 2>/dev/null | cut -f 2 -d ' '`
	if [ "$type" == "$expected" ]; then
		return 0
	elif [ "$type" == "$expected-3d" ]; then
		return 0
	else
		return 1
	fi
}

#
#  board_full_cap_support()
#	Returns whether the detected board has fullcap support or not
#	INPUT : empty
#	OUTPUT:
#		0 = board is fullcap
#		1 = board is not fullcap
#
board_full_cap_support () {
	if [ ! -e /proc/dolphin0 ]; then
		return 1
	fi
	cap=0x$(grep MCORE_CAP /proc/dolphin0 | awk '{print $2}')
	
	if [ $(( ($cap >> 30) & 1 )) -eq 1 ]; then
		return 0
	else
		return 1
	fi
}

#
#  board_low_cap_support()
#	Returns whether the detected board has lowcap support or not
#	INPUT : empty
#	OUTPUT:
#		0 = board is lowcap
#		1 = board is not lowcap
#
board_low_cap_support () {
	if [ ! -e /proc/dolphin0 ]; then
		return 1
	fi
	cap=0x$(grep MCORE_CAP /proc/dolphin0 | awk '{print $2}')
	
	if [ $(( ($cap >> 29) & 1 )) -eq 1 ]; then
		return 0
	else
		return 1
	fi
}

#
#  board_tls_support()
#	Returns whether the detected board has tls capabilities
#	INPUT : empty
#	OUTPUT:
#		0 = board supports tls
#		1 = board does not support tls
#
board_tls_support () {
	if board_low_cap_support || board_full_cap_support; then
		return 0
	else
		return 1
	fi
}

#
#  board_auro_support()
#	Returns whether the detected board has auro support or not
#	INPUT : empty
#	OUTPUT:
#		0 = board has auro support
#		1 = board doe snot have auro support
#
board_auro_support () {
	if [ ! -e /proc/dolphin0 ]; then
		return 1
	fi
	cap=0x$(grep FPGA_2CAP /proc/dolphin0 | awk '{print $2}')
	if [ -z "$cap" ]; then
		return 1
	fi
	
	if [ $(( $cap & 1 )) -eq 1 ]; then
		return 0
	else
		return 1
	fi
}

#
#  timestamp_to_sec()
#	transforms a KDM formatted timestamp into UTC seconds
#	can be easily compared to current time: date -u +%s
#	INPUT : YYYY-MM-DDTHH:M:S[Z|+|-][HH:MM]
#   example: 1999-12-31T23:59:59+00:00
#	OUTPUT:
#		returns 0 and echoes the timestamp in seconds if timestamp could be transformed
#		else returns 1
#		if input timestamp overruns (year higher than 2037), then return maximum 2038-01-01 in seconds
#   
#
timestamp_to_sec() {
	local year=$(echo $1 | cut -d - -f 1)
	if [ -n "$year" ] && [ $year -gt 2037 ]; then
		date -u -d 2038-01-01 +%s
		return
	fi
	local date=$(echo $1 | sed -e s/[T]/\ /g)
	local first_part=$(echo $date | awk '{print $1}')
	local second_part=$(echo $date | awk '{print $2}')
	[ -z "$first_part" ] || [ -z "$second_part" ] && return 1
	local seconds=$(( (10#${second_part:0:2}*3600) + (10#${second_part:3:2}*60) + 10#${second_part:6:2} ))
	local separator=${second_part:8:1}
	local remainder=${second_part:9:5}
	
	# make sure we do not return errors if timestamp exceed 32bit limit (~2038)
	if [ $year -ge 2038 ]; then
		echo $(date -u -d "UTC 2038-01-01 0 secs" +\%s)
		return 0
	fi
	
	if [ -z "$separator" ]; then
		local timezone=$(date +%z)
		separator=${timezone:0:1}
		remainder="${timezone:1:2}:${timezone:4:2}"
	fi
	case "$separator" in
		Z)
			;;
		-)
			seconds=$(( ${seconds} + ((10#${remainder:0:2}*3600) + (10#${remainder:3:2}*60)) ))
			;;
		+)
			seconds=$(( ${seconds} - ((10#${remainder:0:2}*3600) + (10#${remainder:3:2}*60)) ))
			;;
		*)
			return 1
			;;
	esac
	
	date -u -d "UTC $first_part $seconds secs" +%s
}

#
#  sec_to_timestamp()
#	transforms a second timestamp into a KDM formatted timestamp
#	INPUT : timestamp in seconds (UTC)
#	OUTPUT: YYYY-MM-DDTHH:M:S[+|-][HH:MM]
#   example: 1999-12-31T23:59:59+00:00
#   returns 0 and echoes the timestamp
#
sec_to_timestamp() {
	local TZ=$(date +%z)
	local TZ_SIGN=${TZ:0:1}
	local TZ_HOUR=$(( 10#${TZ:1:2} ))
	local TZ_MINUTE=$(( 10#${TZ:3:2} ))
	# maximum supported time in seconds
	if [ $1 -gt 2147483647 ]; then
		date -d "UTC 1970-01-01 2147483647 seconds" +%FT%T${TZ:0:3}:${TZ:3:2}
	else
		date -d "UTC 1970-01-01 $1 seconds" +%FT%T${TZ:0:3}:${TZ:3:2}
	fi
}
