# Copyright 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

description     "Start servod"
author          "chromium-os-dev@chromium.org"

# Stop servod while shutting down.
stop on stopped system-services

respawn

# If you change the respawn limit, change the log rotation, below.
respawn limit 3 10

# This upstart job takes in 5 args, PORT, BOARD, SERIAL, CONFIG and DUAL_V4.
#  * Default PORT is 9999.
#  * The config file is determined by the port, and contains settings for
#    BOARD (mandatory) and SERIAL (optional, unless there's more than one
#    servo) and CONFIG (optional) used for passing an extra overlay file
#    to load.
#  * DUAL_V4 (optional) is used to determine whether a v4 with micro and ccd
#    should use both
#  * Parameters are taken from the config file.
#  * Parameters on the `start` command will initialize/replace settings in the
#    config file.

env PORT=9999
env BOARD=
env MODEL=
env SERIAL=
env CONFIG=
env DUAL_V4=
env CONFIG_FILE_DIR="/var/lib/servod"
# Maximum log file number to keep around per log-level/port
# Each file is at most ~100KiB when compressed, 2MiB uncompressed. The occupancy
# should not exceed 30MiB (uncompressed) + ~102MiB (compressed) = ~132MiB
env LOG_BACKUP_COUNT=1024

import PORT
import BOARD
import MODEL
import SERIAL
import CONFIG
import DUAL_V4

instance $PORT


pre-start script
  LOG="/var/log/servod_$PORT.STARTUP.log"
  {
    mkdir -p /var/lib/servod

    . /usr/share/cros/servod_utils.sh

    log_output \
        "Pre-start PORT=$PORT BOARD=$BOARD MODEL=$MODEL SERIAL=$SERIAL."

    for CMD in iptables ip6tables ; do
      $CMD -A INPUT -p tcp --dport $PORT -j ACCEPT ||
        logger -t "${UPSTART_JOB}" "Failed to configure $CMD."
    done

    CONFIG_FILE=$CONFIG_FILE_DIR/config_$PORT

    log_output \
        "Update config. PORT=$PORT BOARD=$BOARD MODEL=$MODEL SERIAL=$SERIAL."

    # We'll want to update the config file with all the args passed in.
    update_config $CONFIG_FILE BOARD $BOARD
    update_config $CONFIG_FILE MODEL $MODEL
    update_config $CONFIG_FILE SERIAL $SERIAL
    update_config $CONFIG_FILE CONFIG $CONFIG
    update_config $CONFIG_FILE DUAL_V4 $DUAL_V4

    # Load all config values, especially the SERIAL, from the latest config file
    # in case of missing from command line.
    . $CONFIG_FILE

    log_output "Store servo hub location and servo micro serial if presents. "\
        "$CONFIG_FILE $SERIAL"
    cache_servov4_hub_and_servo_micro $CONFIG_FILE $SERIAL

    log_output "Pre-start complete."
  } > $LOG 2>&1
end script

script
  LOG="/var/log/servod_$PORT.STARTUP.log"
  SERVO_MICRO_VIDPID=18d1:501a
  SERVO_V4_VIDPID=18d1:501b

  logger -t "${UPSTART_JOB}" "servod.conf start."
  . /usr/share/cros/servod_utils.sh
  logger -t "${UPSTART_JOB}" "Loaded servod_utils.sh."

  { log_output "Load config file."
    CONFIG_FILE=$CONFIG_FILE_DIR/config_$PORT
    if [ ! -f $CONFIG_FILE ]; then
      log_output "No configuration file ($CONFIG_FILE); terminating"
      stop
      exit 0
    fi

    # Config file must have the board and serial (in multi-servo environment)
    # declared like so:
    # BOARD=veyron_minnie
    # SERIAL=1234
    . $CONFIG_FILE
    if [ -z "$BOARD" ]; then
      log_output "No board specified; terminating"
      stop
      exit 0
    fi

    MODEL_MSG=""
    MODEL_FLAG=""
    if [ -n "$MODEL" ]; then
      MODEL_FLAG="--model ${MODEL}"
      MODEL_MSG=" model ${MODEL}"
    fi

    SERIAL_FLAG=""
    SERIAL_MSG=""
    if [ -z "$SERIAL" ]; then
      log_output "No serial specified"
    else
      SERIAL_FLAG="--serialname ${SERIAL}"
      SERIAL_MSG="using servo serial $SERIAL"
    fi

    log_output \
      "Launching servod for $BOARD $MODEL_MSG on port $PORT $SERIAL_MSG"
    BOARD_FLAG="--board ${BOARD}"
    PORT_FLAG="--port ${PORT}"

    if [ "$DEBUG" = "1" ]; then
      DEBUG_FLAG="--debug"
    else
      DEBUG_FLAG=""
    fi

    CONFIG_FLAG=""
    if [ ! -z "$CONFIG" ]; then
      CONFIG_FLAG="--config ${CONFIG}"
    fi

    if [ "$DUAL_V4" = "1" ]; then
      DUAL_V4_FLAG="--allow-dual-v4"
    else
      DUAL_V4_FLAG=""
    fi

    if [ -n "$SERIAL" ]; then
      log_output "Restart servo v4 and hub"
      # Slam this device just in case.
      # If the serial number is non-responsive, no problem, we cached the
      # path on startup.
      slam_servov4_hub "${HUB}"

      if [ -n "${SERVO_MICRO_SERIAL}" ]; then
        update_firmware "servo_micro" "${SERVO_MICRO_SERIAL}" \
            "${SERVO_MICRO_VIDPID}"
      fi
      update_firmware "servo_v4" "${SERIAL}" "${SERVO_V4_VIDPID}"
      # We need to wait for the servo to finish booting and
      # export its usb endpoints before calling servod.
      sleep 5
    fi
  } >>$LOG 2>&1

  exec servod --host 0.0.0.0 \
              --log-dir-backup-count $LOG_BACKUP_COUNT \
              $BOARD_FLAG \
              $MODEL_FLAG \
              $SERIAL_FLAG \
              $PORT_FLAG \
              $DEBUG_FLAG \
              $CONFIG_FLAG \
              $DUAL_V4_FLAG
end script

pre-stop script
  # Log that the turn-down is coming from upstart rather than another source.
  dut-control -p $PORT "log_msg:Turning down servod from upstart script."
end script

post-stop script
  for CMD in iptables ip6tables ; do
    $CMD -D INPUT -p tcp --dport $PORT -j ACCEPT || true
  done
end script
