Difference between revisions of "Firewire Priming"

From MythTV Official Wiki
Jump to: navigation, search
(One Tuner Priming Script: Added reminder to add node flag on 6200ch)
(Fryfrog's Two Tuner Version)
Line 101: Line 101:
  
 
== Fryfrog's Two Tuner Version ==
 
== Fryfrog's Two Tuner Version ==
I created the following script because I was having issues with firewire, and unlike the original author I have 2x firewire cable boxes to deal withSince the original was hard coded, I would need 2 copies of the script and there was some other items I wanted to fix.  So I took the time to re-do it, and the result is below and it still requires the 6200ch program.  It also leaves out some un-needed tests.  I'd suggest downloading it rather than copy/pasting from here, but what ever works for you.  Any suggestions and comments are welcome.
+
The latest version (1.0.3) is the even more, most super amazing flexible and useful firewire changing scriptIt supports 'p2p' as well as 'broadcast', allows many options to be fed in as -o type options and is generally better all around.  It requires an external channel changing script like '6200ch' as well as the 'firewire_tester' program that comes with MythTV in the ./contrib dirFinally, it makes use of the 'test-mpeg2' and 'plugctl' programs that come with libiec61883.
  
 
[http://fryfrog.com/files/sure-change.zip Download latest version]
 
[http://fryfrog.com/files/sure-change.zip Download latest version]
  
#!/bin/bash
+
<pre>
# Released under the GPL, 2006
+
#!/bin/bash
# Current Version:  1.01
+
# Released under the GPL, 2006
# Revision history
+
# Current Version:  1.03
# Version 1.01, Improved debugging output/formatting!
+
#
# Version 1.0, initial release!
+
# Revision history:
# Remember, the -h option (and making a mistake) gives a usage summary!
+
# 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
# Firewire channel changing and test script, re-written by fryfrog at gmail.com, fryfrog.com
+
#                input from firewire before testing.
# Original idea from Sean Donovan, techonfoot.com
+
# Version 1.0.1, Improved debugging output/formatting!
#
+
# Version 1.0.0, Initial release!
# 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.
+
# Remember, the -h option (and making a mistake) gives a usage summary!
# 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
+
# Firewire channel changing and test script, re-written by fryfrog at gmail.com, fryfrog.com
# and node, the same script can be used for those with more than one HD tuner.
+
# Original idea from Sean Donovan, techonfoot.com
#
+
#
# It also requires *no* outside scripts except for the 6200ch channel changer,
+
# This script has been completely re-written to be more robust and useful than
# for which I have included a small patch that allows it to change the channel
+
# the original version.  It can be passed the port, node and number of tries.
# on yet another model of the DCT6412 (HD-DVR).
+
# 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
# The script also uses variables for a large portion of the script, allowing
+
# and node, the same script can be used for those with more than one fw tuner.
# (hopefully) it to be much easier to change and adapt to the future or your
+
#
# needs.
+
# 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
# Example usage:
+
# needs.
# 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
+
# Requirements:
# debug messages.  Script can be found in /usr/local/bin/sure-change.sh
+
# 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
# Entry in mythtv-setup, input connections, channel changing script.
+
# the "test-mpeg2" & "plugctl" programs that should be part of libiec61883
# /usr/local/bin/sure-change.sh -p 0 -n 0 -t 5 -d
+
#
# Entry for second box
+
# Example usage:
# /usr/local/bin/sure-change.sh -p 0 -n 1 -t 5 -d
+
# 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
# Default values for port, node, debug and verbose
+
# debug messages.  Script can be found in /usr/local/bin/sure-change.sh
# These can be changed if desired, or fed via options
+
#
PORT=0
+
# Entry in mythtv-setup, input connections, channel changing script.
NODE=0
+
# /usr/local/bin/sure-change.sh -p 0 -n 0 -t 5 -d
DEBUG=0
+
# Entry for second box
VERBOSE=0
+
# /usr/local/bin/sure-change.sh -p 0 -n 1 -t 5 -d
TRIES=5
+
#
+
# Default values for port, node, debug and verbose
# Values for external binarys / scripts
+
# These can be changed if desired, or fed via options
# You probably want to point these to the correct place
+
MODE="p"
CHANNEL_CHANGER="/usr/local/bin/6200ch"
+
PORT=0
TEST_MPEG2="/usr/bin/test-mpeg2"
+
NODE=0
PLUGCTL_PROG="/usr/bin/plugctl"
+
DEBUG=0
TEST_FILE="/tmp/testcap.ts"
+
VERBOSE=0
+
TRIES=5
# Lonely variable used for loop, dont touch!
+
TIME=1
X=0
+
 
+
# Values for external binarys / scripts
# Usage function
+
# You probably want to point these to the correct place
usage() {
+
CHANNEL_CHANGER="/usr/local/bin/6200ch"
    echo "Usage:  [-p <port>] [-n <node>] [-t <tries>] [-v] [-d] [-h] <channel>"
+
FIREWIRE_TESTER="/usr/local/bin/firewire_tester"
    echo "-p <port>    ** The adapter port, default of 0"
+
TEST_MPEG2="/usr/bin/test-mpeg2"
    echo "-n <node>    ** The node of device, default of 0"
+
PLUGCTL_PROG="/usr/bin/plugctl"
    echo "-t <tries>  ** Number of reset and test attemps"
+
TEST_FILE="/tmp/testcap.ts"
    echo "-v          ** Verbose output"
+
 
    echo "-d          ** Debug output"
+
# Lonely variable used for loop, dont touch!
    echo "-h           ** Help and usage"
+
X=0
    echo "<channel>    ** Channel being changed to"
+
 
}
+
# Usage function
+
usage() {
# Debug & Verbose output
+
  echo " Usage:  [-p <port>] [-n <node>] [-t <tries>] [-v] [-d] [-h] <channel>"
inform() {
+
  echo "   -m <mode>    ** [p]2p or [b]roadcast"
    TIMESTAMP=`date +"%F %T"`
+
  echo "  -p <port>    ** The adapter port, default of 0"
    MSG="$1"
+
  echo "   -n <node>    ** The node of device, default of 0"
    echo "${TIMESTAMP} - ${MSG}"
+
  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"
# Port setting function
+
  echo "                  with 5 second time out is 25 seconds until fail!"
set_port() {
+
  echo "   -v           ** Verbose output"
    PORT=$1
+
  echo "   -d          ** Debug output"
    (( DEBUG )) && inform "Port used: ${PORT}."
+
  echo "  -h          ** Help and usage"
}
+
  echo "   <channel>    ** Channel being changed to"
+
}
# Node setting function
+
 
set_node() {
+
# Debug & Verbose output
    NODE=$1
+
inform() {
    (( DEBUG )) && inform "Node used: ${NODE}."
+
  TIMESTAMP=`date +"%F %T"`
}
+
  MSG="$1"
+
  echo "${TIMESTAMP} - ${MSG}"
set_firewire() {
+
}
    ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} ompr.bcast_channel=0
+
 
    ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].channel=${NODE}
+
# Mode setting function
    ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].bcast_connection=0
+
set_mode() {
    ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].n_p2p_connections=1
+
  MODE="$1"
    (( DEBUG )) && inform "Default firewire settings applied to port ${PORT}, node ${NODE}."
+
  if [[ "${MODE}" != "p" ]] && [[ "${MODE}" != "b" ]]; then
}
+
      echo "Invalid mode specified, use [p]2p or [b]roadcast"
+
      echo "${MODE}"
reset_firewire() {
+
      usage
    ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].n_p2p_connections=0
+
      exit 1
    read_firewire
+
  fi
    (( DEBUG )) && inform "Reset firewire settings on port ${PORT}, node ${NODE}."
+
  (( DEBUG )) && inform "Mode used: ${MODE}"
}
+
}
+
 
read_firewire() {
+
# Port setting function
    ${TEST_MPEG2} -r ${NODE} 2> /dev/null > ${TEST_FILE} &
+
set_port() {
    sleep 1
+
  PORT=$1
    killall ${TEST_MPEG2}
+
  (( DEBUG )) && inform "Port used: ${PORT}."
    (( DEBUG )) && inform "Attempted read of port ${PORT}, node ${NODE}."
+
}
}
+
 
+
# Node setting function
# Test firewire
+
set_node() {
test_firewire() {
+
  NODE=$1
    # Check if firewire is actually working
+
  (( DEBUG )) && inform "Node used: ${NODE}."
    read_firewire
+
}
+
 
    if [ -s "${TEST_FILE}" ] ; then
+
set_p2p() {
      (( DEBUG )) && inform "Firewire test success."
+
  ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} ompr.bcast_channel=0
      go_byebye
+
  ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].channel=${NODE}
    else
+
  ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].bcast_connection=0
      (( DEBUG )) && inform "Firewire test failed."
+
  ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].n_p2p_connections=1
    fi
+
  (( DEBUG )) && inform "Default firewire settings applied to port ${PORT}, node ${NODE}."
}
+
}
+
 
# Exit
+
reset_p2p() {
go_byebye() {
+
  ${PLUGCTL_PROG} -p ${PORT} -n ${NODE} opcr[0].n_p2p_connections=0
    clean
+
  read_p2p
    (( $1 )) && exit 1
+
  (( DEBUG )) && inform "Reset firewire settings on port ${PORT}, node ${NODE}."
    exit 0
+
}
}
+
 
+
read_p2p() {
# Cleanup
+
  ${TEST_MPEG2} -r ${NODE} 2> /dev/null > ${TEST_FILE} &
clean() {
+
  sleep ${TIME}
    if [ -f ${TEST_FILE} ]; then
+
  killall ${TEST_MPEG2}
      (( DEBUG )) && inform "Test file found, deleting."
+
  (( DEBUG )) && inform "Attempted read of port ${PORT}, node ${NODE}."
      rm ${TEST_FILE}
+
}
    fi
+
 
}
+
# Test firewire
+
test_firewire() {
# Begin main!
+
  # set mode, node and port options
if [ $# == 0 ]; then
+
  TEST_OPTS="-${MODE} -P ${PORT} -n ${NODE}"
 +
  # 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 "Channel ${CHANNEL} selected and firewire working!"
 +
      go_byebye
 +
  else
 +
      (( DEBUG )) || (( VERBOSE )) && inform "Channel ${CHANNEL} selected but firewire NOT working."
 +
  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
 +
 
 +
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
 
   usage
 
   go_byebye
 
   go_byebye
fi
+
else
+
  CHANNEL="$1"
while getopts p:n:t:vdh OPTION;
+
fi
do
+
 
    case ${OPTION} in
+
clean
      p) set_port ${OPTARG}
+
 
          ;;
+
# Attempt to change the channel
      n) set_node ${OPTARG}
+
(( DEBUG )) || (( VERBOSE )) && inform "Trying ${TRIES} times to get channel ${CHANNEL}"
          ;;
+
${CHANNEL_CHANGER} -p ${PORT} -n ${NODE} ${CHANNEL}
      v) VERBOSE=1
+
(( $? )) && (( DEBUG )) && inform "External ${CHANNEL_CHANGER} failure!" && exit 1
          ;;
+
 
      d) DEBUG=1
+
(( DEBUG )) && inform "Initial pre-test of firewire."
          ;;
+
test_firewire
      t) TRIES=${OPTARG}
+
 
          ;;
+
# If fire wire isn't working, try to reset it
      *) usage
+
while [ ${X} -lt ${TRIES} ]
          exit 0
+
do
          ;;
+
  X=$((X+=1))
    esac;
+
  (( DEBUG )) && inform "Attempt ${X} of ${TRIES}..."
done
+
 
+
  if [[ "${MODE}" == "p" ]]; then
shift $(($OPTIND - 1))
+
      # Reset p2p and do a capture, aparantly this helps with the reset.
+
      reset_p2p
if [ "$1" == "" ]; then
+
 
    echo "You forgot to specify a <channel>!"
+
      # Reset to known-good settings
    usage
+
      set_p2p
    go_byebye
+
  elif [[ "${MODE}" == "b" ]]; then
else
+
      # Use firewire tester to reset broadcast mode
    CHANNEL="$1"
+
 
fi
+
      # set mode, node and port options
+
      TEST_OPTS="-B -P ${PORT} -n ${NODE}"
clean
+
      # set debug/verbose option
+
      (( DEBUG )) || (( VERBOSE )) && TEST_OPTS="${TEST_OPTS} -v"
# Attempt to change the channel
+
 
(( DEBUG )) || (( VERBOSE )) && inform "Trying ${TRIES} times to get channel ${CHANNEL}"
+
      # run test with above assigned options
${CHANNEL_CHANGER} -p ${PORT} -n ${NODE} ${CHANNEL}
+
      ${FIREWIRE_TESTER} ${TEST_OPTS}
(( $? )) && (( DEBUG )) && inform "External ${CHANNEL_CHANGER} failure!" && exit 1
+
  fi
+
 
(( DEBUG )) && inform "Initial pre-test of firewire."
+
  # Test again after reset, hope it works!
test_firewire
+
  test_firewire
+
done
# If fire wire isn't working, try to reset it
+
 
while [ ${X} -lt ${TRIES} ]
+
(( DEBUG )) || (( VERBOSE )) && inform "${X} attempts failed, could not change to ${CHANNEL} and recieve signal via firewire"
do
+
go_byebye 1
    X=$((X+=1))
+
</pre>
    (( DEBUG )) && inform "Attempt ${X} of ${TRIES}..."
 
 
    # Reset p2p and do a capture, aparantly this helps with the reset.
 
    reset_firewire
 
 
 
    # Reset to known-good settings
 
    set_firewire
 
 
    # Test again after reset, hope it works!
 
    test_firewire
 
done
 
 
(( DEBUG )) || (( VERBOSE )) && inform "${X} attempts failed, could not change to ${CHANNEL} and recieve signal via firewire"
 
go_byebye 1
 
 
 
[[Category:HOWTO]]
 
[[Category:HOWTO]]
 
[[Category:Scripts]]
 
[[Category:Scripts]]

Revision as of 20:14, 10 November 2006

Introduction

Below are two firewire scripts which change channels and prime the firewire before MythTV starts to record. The first is for a one tuner setup and the second is a more flexible two tuner setup.

Both require the 6200ch helper program:

Required 6200ch change channel script

You also need the 6200ch change channel script which you can compile in the /usr/share/doc/mythtv-0.20/contrib/channel_changers directory (read the README). Don't forget you will need to get the headers for the kernel (yum install kernel-devel). On RedHat Fedora 5, you will also need the libavc1394-devel package, (yum install libavc1394-devel).


One Tuner Priming Script

This is a script which is invoked each time a channel change is requested and a firewire connection needs to be working. It first tests the existing p2p and channel settings and if OK, test to see if the result from test-mpeg2 is a non-zero file which means the firewire connection is working. If the result is negative for any of the p2p, channel and non-zero file tests, it then tries to use plugctl to reset the firewire connection, and then runs the test-mpeg2 test again. It repeats ten times and if it gets 10 non-zero results, it fails.

Note:

  • It relies on the 6200ch change channel script.
  • It assumes the firewire connection is on node 1 and p2p routing (not bcast).
  • If your node is not 1, be sure to add the correct node in front of the channel change command. IE: '/home/6200ch -n2 $1' rather than '/home/6200ch $1'
  • If you run mythbackend with a log file, i.e. "mythbackend >> /home/mythbackend_log.log &", the echo statements below will appear in the log which is useful for debugging.


#!/bin/bash
# v1.02, a Firewire change channel and test script by Sean Donovan, techonfoot.com
# Released under GPL, 2006
# Revision history
# v1.02 - Fixed the unnecessary kill_test.sh script
# v1.01 - Added detection for conditions that work intermittently, i.e. test-mpeg2 will work
#         but the next capture by MythTV won't.  Usually when p2p is 0 or channel <> 63.
#         Fixed a bug whereby the script expects the kill_test.sh script in the /home directory.
# v1.00 - Genesis
#
# ------------------------
# Prime the variables used to exit the while loop and set error messages 
# C2 is used to avoid the while loop or exit it, if the firewire is primed 
# C3 is used to notify either an error condition (=1) or not (=0)
C2=0
C3=1
# Change the channel
/home/6200ch $1
# Then change into the directory with the kill_test.sh script
cd /home
# First check to make sure the firewire port is set up correctly or the
# "Is it primed?" test could report positive but the firewire is in a failing state.
T1=`plugctl -n 1 opcr[0].n_p2p_connections`
T2=`plugctl -n 1 opcr[0].channel`
if [ $T1 != "1" ] ; then
       # Oops, p2p isn't one, let it go into the while loop for reset.
       echo "###### Oops, p2p isn't one!  Going to reset Firewire"  
elif [ $T2 != "63" ] ; then
       # Oops, the channel isn't 63
       echo "###### Oops, the channel isn't 63!  Going to reset Firewire"  
else 
       # Now check if the firewire is primed already, then do nothing:
       test-mpeg2 -r 1 > testcap.ts &
       sleep 1
       killall test-mpeg2
       if [ -s testcap.ts ] ; then
               echo "#################"
               echo "# Firewire is primed!!!!!!!!!!!!"
               echo "################"
               # No error and 
               C3=0
               # Don't enter the while loop, the firewire is working already...
               C2=11
       fi
fi	
# While the counter is less then or equal to 10
# Enter the while loop and reset the firewire
while [ $C2 -le 10 ]
do
       C2=$((C2+=1))
       echo "##### Now Changing the Firewire setup for the $C2 time "
       # First set p2p to 0 and do a capture which seems to reset everything
       plugctl -n 1 opcr[0].n_p2p_connections=0
       test-mpeg2 -r 1 > testcap.ts &
       sleep 1
       killall test-mpeg2
       # Now set it to what seems to work best, at least for the DCT-6200 series tuner...
       plugctl -n 1 ompr.bcast_channel=0
       plugctl -n 1 opcr[0].channel=63
       plugctl -n 1 opcr[0].bcast_connection=0
       plugctl -n 1 opcr[0].n_p2p_connections=1
       test-mpeg2 -r 1 > testcap.ts &
       sleep 1
       killall test-mpeg2
       if [ -s testcap.ts ] ; then
               echo "################"
               echo "# Firewire is primed!!!!!!!!!!!!"
               echo "################"
               C3=0
               # Exit the loop
               C2=11
       fi	
       # Otherwise repeat the loop
done
# Now print the error codes if any.
if [ $C3 -eq 1 ] ; then
       echo "XXXXXXXXXXXXXXXX"
       echo "X Craappp it failed after ten tries - the tuner on?"
       echo "XXXXXXXXXXXXXXX"
fi
# Clean Up
rm testcap.ts

Fryfrog's Two Tuner Version

The latest version (1.0.3) is the even more, most super amazing flexible and useful firewire changing script. It supports 'p2p' as well as 'broadcast', allows many options to be fed in as -o type options and is generally better all around. It requires an external channel changing script like '6200ch' as well as the 'firewire_tester' program that comes with MythTV in the ./contrib dir. Finally, it makes use of the 'test-mpeg2' and 'plugctl' programs that come with libiec61883.

Download latest version

#!/bin/bash
# Released under the GPL, 2006
# Current Version:  1.03
#
# Revision history:
# 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/bin/test-mpeg2"
PLUGCTL_PROG="/usr/bin/plugctl"
TEST_FILE="/tmp/testcap.ts"

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

# 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}."
}

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}."
}

# Test firewire
test_firewire() {
   # set mode, node and port options
   TEST_OPTS="-${MODE} -P ${PORT} -n ${NODE}"
   # 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 "Channel ${CHANNEL} selected and firewire working!"
      go_byebye
   else
      (( DEBUG )) || (( VERBOSE )) && inform "Channel ${CHANNEL} selected but firewire NOT working."
   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

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}"
${CHANNEL_CHANGER} -p ${PORT} -n ${NODE} ${CHANNEL}
(( $? )) && (( DEBUG )) && inform "External ${CHANNEL_CHANGER} failure!" && exit 1

(( DEBUG )) && inform "Initial pre-test of firewire."
test_firewire

# If fire wire isn't working, try to reset it
while [ ${X} -lt ${TRIES} ]
do
   X=$((X+=1))
   (( 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
   elif [[ "${MODE}" == "b" ]]; then
      # Use firewire tester to reset broadcast mode
   
      # set mode, node and port options
      TEST_OPTS="-B -P ${PORT} -n ${NODE}"
      # set debug/verbose option
      (( DEBUG )) || (( VERBOSE )) && TEST_OPTS="${TEST_OPTS} -v"

      # run test with above assigned options
      ${FIREWIRE_TESTER} ${TEST_OPTS}
   fi

   # Test again after reset, hope it works!
   test_firewire
done

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