Multi Tuner Firewire Priming Script

From MythTV Official Wiki
Jump to: navigation, search

Author Fryfrog
Description Fryfrog's multi-tuner firewire priming script
Supports


Fryfrog's Multi Tuner Firewire Priming Script

The latest version is a fairly big cleanup and re-tune. It now uses the firewire bus reset available in the "latest" version of firewire_tester. This means you may need to grab the source for it (it is only one file) from SVN head. It is worth it, I think. You can always modify the script a little if you don't want to use it (just deleting two lines should do it). It should now be faster in cases where things are working, and it uses the "single" packet method with 6200ch. I am having "better" luck with it now, but firewire still isn't work 100% for me. I'm almost ready to move to SVN with all the new firewire features.

Download latest version


Script.png sure-change.sh

#!/bin/bash
# Released under the GPL, 2006
# Current Version:  1.0.6
#
# Revision history:
# Version 1.0.6, Added auto-detection of neccessary programs.  Still includes
#                manual locations, but if that fails it will try auto-detecting
#                and finally fail telling you it can't find the utility.
# Version 1.0.5, Lots of minor changes.  The lenght of time spent fixing will
#                now depend on how many times it has looped.  This means that if
#                everything is working, it will be fast.  As it fails, it will spend
#                longer and longer trying to fix.  I also added in a re-tune
#                of the channel after X attemps and a firewire port reset after
#                Y attempts.  I cleaned up the code a bit, and it seems to be
#                working a bit better for me.
#                ** IMPORTANT ** -- The mode options "p" and "b" where changed to
#                "p" and "B" (sorry).
# Version 1.0.4, Added support for the -R reset firewire bus command in svn versions of the
#                firewire_tester program.
# Version 1.0.3, Added support for p2p *and* broadcast, using "firewire_tester"
# Version 1.0.2, Added a "seconds" option controlling how long it gets
#                input from firewire before testing.
# Version 1.0.1, Improved debugging output/formatting!
# Version 1.0.0, Initial release!
#
# Remember, the -h option (and making a mistake) gives a usage summary!
#
# Firewire channel changing and test script, re-written by fryfrog at gmail.com, fryfrog.com
# Original idea from Sean Donovan, techonfoot.com
#
# This script has been completely re-written to be more robust and useful than
# the original version.  It can be passed the port, node and number of tries.
# it also has a verbose and debug mode to help track down issues.  The defaults
# should be very similar to the original script.  Since this one can take port
# and node, the same script can be used for those with more than one fw tuner.
#
# The script also uses variables for a large portion of the script, allowing
# (hopefully) it to be much easier to change and adapt to the future or your
# needs.
#
# Requirements:
# You will need a channel changer (like 6200ch for the DCT series of STBs),
# the "firewire_tester" program that comes in ./contrib of MythTV, and finally
# the "test-mpeg2" & "plugctl" programs that should be part of libiec61883
#
# Example usage:
# 2x firewire cable boxes.  `plugreport` shows them on adapter 0, node 0 & 1.
# After a bit of manual, 5 tries is found to be "ideal" and you would like
# debug messages.  Script can be found in /usr/local/bin/sure-change.sh
#
# Entry in mythtv-setup, input connections, channel changing script.
# /usr/local/bin/sure-change.sh -p 0 -n 0 -t 5 -d
# Entry for second box
# /usr/local/bin/sure-change.sh -p 0 -n 1 -t 5 -d
#
# Default values for port, node, debug and verbose
# These can be changed if desired, or fed via options
MODE="p"
PORT=0
NODE=0
DEBUG=0
VERBOSE=0
TRIES=5
TIME=1

# Values for external binarys / scripts
# You probably want to point these to the correct place

CHANNEL_CHANGER="/usr/local/bin/6200ch"
FIREWIRE_TESTER="/usr/local/bin/firewire_tester"
TEST_MPEG2="/usr/local/bin/test-mpeg2"
PLUGCTL_PROG="/usr/bin/plugctl"
TEST_FILE="/tmp/testcap.ts"

# Lonely variable used for loop, dont touch!
X=1

# Usage function
usage() {
   echo " Usage:  [-p <port>] [-n <node>] [-t <tries>] [-v] [-d] [-h] <channel>"
   echo "   -m <mode>    ** [p]2p or [B]roadcast"
   echo "   -p <port>    ** The adapter port, default of 0"
   echo "   -n <node>    ** The node of device, default of 0"
   echo "   -t <tries>   ** Number of reset and test attemps"
   echo "   -s <seconds> ** Number of seconds to record for test, default of 1"
   echo "                   strongly suggest something in the 1-2 range, 5 tries"
   echo "                   with 5 second time out is 25 seconds until fail!"
   echo "   -v           ** Verbose output"
   echo "   -d           ** Debug output"
   echo "   -h           ** Help and usage"
   echo "   <channel>    ** Channel being changed to"
}

# Debug & Verbose output
inform() {
   TIMESTAMP=`date +"%F %T"`
   MSG="$1"
   echo "${TIMESTAMP} - ${MSG}"
}

# Mode setting function
set_mode() {
   MODE="$1"
   if [[ "${MODE}" != "p" ]] && [[ "${MODE}" != "B" ]]; then
      echo "Invalid mode specified, use [p]2p or [B]roadcast"
      echo "${MODE}"
      usage
      exit 1
   fi
   (( DEBUG )) && inform "Mode used: ${MODE}"
}

# Port setting function
set_port() {
   PORT=$1
   (( DEBUG )) && inform "Port used: ${PORT}."
}

# Node setting function
set_node() {
   NODE=$1
   (( DEBUG )) && inform "Node used: ${NODE}."
}

set_p2p() {
   ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} ompr.bcast_channel=0
   ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].channel=${NODE}
   ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].bcast_connection=0
   ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].n_p2p_connections=1
   (( DEBUG )) && inform "Default firewire settings applied to port ${PORT}, node ${NODE}."
}

set_channel() {
   # set mode, node and other options
   CHAN_OPTS="-s -p ${PORT} -n ${NODE} ${CHANNEL}"
   # set debug option
   (( DEBUG )) && CHAN_OPTS="${CHAN_OPTS} -v"

   if [[ ${DEBUG} -eq 1 ]]; then
      ${CHANNEL_CHANGER} ${CHAN_OPTS}
   else
      ${CHANNEL_CHANGER} ${CHAN_OPTS} 2>&1 >/dev/null
   fi
   (( $? )) && inform "External ${CHANNEL_CHANGER} failure!" && exit 1
   (( DEBUG )) || (( VERBOSE )) && inform "Selected channel ${CHANNEL}."
}

reset_p2p() {
   ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].n_p2p_connections=0
   read_p2p
   (( DEBUG )) && inform "Reset firewire settings on port ${PORT}, node ${NODE}."
}

read_p2p() {
   ${TEST_MPEG2} -r ${NODE} 2> /dev/null > ${TEST_FILE} &
   sleep ${TIME}
   killall ${TEST_MPEG2}
   (( DEBUG )) && inform "Attempted read of port ${PORT}, node ${NODE}."
}

# Reset the firewire bus, using new firewire_tester -R option
reset_firewire_bus() {
   # set mode, node and port options
   TEST_OPTS="-R -P ${PORT}"
   # set debug/verbose option
   (( DEBUG )) || (( VERBOSE )) && TEST_OPTS="${TEST_OPTS} -v"

   # run test with above assigned options
   if [[ ${DEBUG} -eq 1 ]]; then
      ${FIREWIRE_TESTER} ${TEST_OPTS}
   else
      ${FIREWIRE_TESTER} ${TEST_OPTS} 2>&1 >/dev/null
   fi

   if [[ $? -eq 0 ]]; then
      (( DEBUG )) || (( VERBOSE )) && inform "Reset of firewire port ${PORT} successful."
   else
      (( DEBUG )) || (( VERBOSE )) && inform "Reset of firewire port ${PORT} failed."
   fi
}

# Test firewire
test_firewire() {
   # set mode, node and port options (using X results in
   # longer attempts later in the loop
   TEST_OPTS="-${MODE} -P ${PORT} -n ${NODE} -r ${X}"
   # set debug/verbose option
   (( DEBUG )) && TEST_OPTS="${TEST_OPTS} -v"
   
   # run test with above assigned options
   if [[ ${DEBUG} -eq 1 ]]; then
      ${FIREWIRE_TESTER} ${TEST_OPTS}
   else
      ${FIREWIRE_TESTER} ${TEST_OPTS} 2>&1 >/dev/null
   fi

   if [[ $? -eq 0 ]]; then
      (( DEBUG )) || (( VERBOSE )) && inform "Firewire working after ${X} attempts!"
      go_byebye
   else
      (( DEBUG )) || (( VERBOSE )) && inform "Firewire NOT working yet after ${X} attempts."
   fi
}

# Exit
go_byebye() {
   clean
   (( $1 )) && exit 1
   exit 0
}

# Cleanup
clean() {
   if [ -f ${TEST_FILE} ]; then
      (( DEBUG )) && inform "Test file found, deleting."
      rm ${TEST_FILE}
   fi
}

# Begin main!
if [ $# == 0 ]; then
  usage
  go_byebye
fi

# Test 6200ch, try to find it or fail.
if [[ ! -x ${CHANNEL_CHANGER} ]]; then
   if [[ -x `which 6200ch` ]]; then
      CHANNEL_CHANGER="`which 6200ch`"
      inform "${CHANNEL_CHANGER} auto-detected."
   else
      inform "6200ch not found."
      go_byebye
   fi
fi

# Test firewire_tester, try to find it or fail
if [[ ! -x ${FIREWIRE_TESTER} ]]; then
   if [[ -x `which firewire_tester` ]]; then
      FIREWIRE_TESTER="`which firewire_tester`"
      inform "${FIREWIRE_TESTER} auto-detected."
   else
      inform "firewire_tester not found."
      go_byebye
   fi
fi

# Test test-mpeg2, try to find it or fail
if [[ ! -x ${TEST_MPEG2} ]]; then
   if [[ -x `which test-mpeg2` ]]; then
      TEST_MPEG2="`which test-mpeg2`"
      inform "${TEST_MPEG2} auto-detected."
   else
      inform "test-mpeg2 not found."
      go_byebye
   fi
fi

# Test plugctl, try to find it or fail
if [[ ! -x ${PLUGCTL_PROG} ]]; then
   if [[ -x `which plugctl` ]]; then
      PLUGCTL_PROG="`which plugctl`"
      inform "${PLUGCTL_PROG} auto-detected."
   else
      inform "plugctl not found."
      go_byebye
   fi
fi

while getopts m:p:n:t:s:vdh OPTION; 
do
   case ${OPTION} in
      m) set_mode ${OPTARG}
         ;;
      p) set_port ${OPTARG}
         ;;
      n) set_node ${OPTARG}
         ;; 
      v) VERBOSE=1
         ;;
      d) DEBUG=1
         ;;
      t) TRIES=${OPTARG}
         ;;
      s) TIME=${OPTARG}
         ;;
      *) usage
         exit 0
         ;;
   esac;
done

shift $(($OPTIND - 1))

if [ "$1" == "" ]; then
   echo "You forgot to specify a <channel>!"
   usage
   go_byebye
else
   CHANNEL="$1"
fi

clean

# Attempt to change the channel
(( DEBUG )) || (( VERBOSE )) && inform "Trying ${TRIES} times to get channel ${CHANNEL}"
set_channel

# If fire wire isn't working, try to reset it
while [ ${X} -le ${TRIES} ]
do
   (( DEBUG )) && inform "Attempt ${X} of ${TRIES}..."

   if [[ "${MODE}" == "p" ]]; then
      # Reset p2p and do a capture, aparantly this helps with the reset.
      reset_p2p

      # Reset to known-good settings
      set_p2p
   fi

   # If it fails twice, try re-tuning the channel
   if [ $(( X % 3 )) -eq 0 ]; then
      set_channel
   fi

   # If it fails 3 times, reset the firewire bus
   if [ $(( X % 5 )) -eq 0 ]; then
      reset_firewire_bus
   fi

   # Test again after reset, hope it works!
   test_firewire

   X=$((X+=1))
done

(( DEBUG )) || (( VERBOSE )) && inform "${TRIES} attempts failed, could not change to ${CHANNEL} and recieve signal via firewire"
go_byebye 1