#!/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
#
##############################################################################

. /doremi/etc/init.d/functions
test -f /doremi/etc/init.d/functions || USE_FUNCTION=0

#
# 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
MOTHERBOARD_MODEL_X10SLX=11
MOTHERBOARD_MODEL_FUSION2=12
MOTHERBOARD_MODEL_COREAV=13
MOTHERBOARD_MODEL_NP4000=14
MOTHERBOARD_MODEL_X10SLH=15

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=${v_platform}
  fi
  
  if [ "$platform" == "ims" ]; then
    model="fusion"
  elif [ "$platform" == "ims2" ]; then
    model="fusion2"    
  elif [ "$platform" == "le100" ]; then
    model="coreav"
  elif [ "$platform" == "np100" ]; then
    model="coreav"
  elif [ "$platform" == "np4000" ]; then
    model="np4000"
  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
      ;;
    fusion2)
      return $MOTHERBOARD_MODEL_FUSION2
      ;;
    coreav)
      return $MOTHERBOARD_MODEL_COREAV
      ;;
    np4000)
      return $MOTHERBOARD_MODEL_NP4000
      ;;
    *)
      # 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
      ;;
    X10SLX*)
      return $MOTHERBOARD_MODEL_X10SLX
      ;;
    X10SLH*)
       return $MOTHERBOARD_MODEL_X10SLH
      ;;
    *)
      ;;
  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
#      np4000 = np4000 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

  local fpga_2cap=$(grep FPGA_2CAP /proc/dolphin0 | awk '{print $2}')
  if [ -z "$fpga_2cap" ]; then
    fpga_2cap=0
  fi
  fpga_2cap=0x$fpga_2cap

  if [ $(( ($fpga_2cap >> 8) & 1 )) -eq 1 ]; then
    if [ $type == "np4000" ]; then
      return 0
    else
      return 1
    fi
  elif [ $(( ($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
}
