#! /usr/bin/perl -w
#
# Written by Oron Peled <oron@actcom.co.il>
# Copyright (C) 2007, Xorcom
# This program is free software; you can redistribute and/or
# modify it under the same terms as Perl itself.
#
# $Id: twinstar 6417 2009-04-20 13:44:35Z tzafrir $
#
use strict;
use File::Basename;
use Getopt::Std;
BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); }

use Dahdi;
use Dahdi::Hardware;
use Dahdi::Span;
use Dahdi::Xpp;
use Dahdi::Xpp::Xbus;
use Dahdi::Xpp::Mpp;

sub usage {
	die "Usage: $0 {status|jump|enable-wd|disable-wd|ports}\n";
}

our ($opt_v, $opt_x);
getopts('vx') || usage;
@ARGV == 1 or usage;


# Find USB bus toplevel
my $usb_top;
$usb_top = '/dev/bus/usb';
$usb_top = '/proc/bus/usb' unless -d $usb_top;
die "No USB toplevel found\n" unless -d $usb_top;

sub tws_devs() {
	my @devs;
	foreach my $dev (Dahdi::Hardware->device_list) {
		next unless $dev->is_astribank;
		next unless $dev->product =~ /116./;
		push(@devs, $dev->hardware_name);
	}
	return @devs;
}

sub tws_usb_devfile($) {
	my $name = shift || die;
	# Remove prefix
	if($name !~ s/usb://) {
		die "$name is not a USB name\n";
	}
	return "$usb_top/$name";
}

sub tws_show(@) {
	my @usb_devs = @_;
	my $format = "%-15s %-10s %-15s %-10s %-10s\n";

	printf $format, 'DEVICE', 'PORT', 'WATCHDOG', 'POWER0', 'POWER1';
	foreach my $dev (@usb_devs) {
		my $mppinfo = $dev->mppinfo;
		if(!defined $mppinfo) {
			printf STDERR "%s: no MPP information\n", $dev->hardware_name;
			next;
		}
		if(!defined $mppinfo->{TWINSTAR_PORT}) {
			printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name;
			next;
		}
		my $power = $mppinfo->twinstar_power;
		printf $format,
			$dev->hardware_name,
			$mppinfo->twinstar_port,
			($mppinfo->twinstar_watchdog) ? "on" : "off",
			($power->[0]) ? "yes" : "no",
			($power->[1]) ? "yes" : "no";
	}
}

sub tws_portnum($) {
	my $dev = shift || die "Missing dev";
	my $mppinfo = $dev->mppinfo;
	if(!defined $mppinfo) {
		printf STDERR "%s: no MPP information\n", $dev->hardware_name;
		return undef;
	}
	return $mppinfo->twinstar_port;
}

sub tws_showports(@) {
	my @usb_devs = @_;
	foreach my $dev (@usb_devs) {
		my $mppinfo = $dev->mppinfo;
		if(!defined $mppinfo) {
			printf STDERR "%s: no MPP information\n", $dev->hardware_name;
			next;
		}
		if(!defined $mppinfo->{TWINSTAR_PORT}) {
			printf STDERR "%s: no TWINSTAR_PORT information\n", $dev->hardware_name;
			next;
		}
		printf "%s\n", $mppinfo->{TWINSTAR_PORT};
	}
}

sub tws_watchdog($@) {
	my $on = shift;
	die "tws_watchdog() on/off?" unless defined $on;
	my @usb_devs = @_;

	foreach my $dev (@usb_devs) {
		my $mppinfo = $dev->mppinfo;
		if(!defined $mppinfo) {
			printf STDERR "%s: no MPP information\n", $dev->hardware_name;
			next;
		}
		$mppinfo->mpp_setwatchdog($on);
	}
}

sub tws_jump(@) {
	my @usb_devs = @_;

	foreach my $dev (@usb_devs) {
		my $mppinfo = $dev->mppinfo;
		if(!defined $mppinfo) {
			printf STDERR "%s: no MPP information\n", $dev->hardware_name;
			next;
		}
		$mppinfo->mpp_jump;
	}
}

sub dev_list() {
	my @devs;
	foreach my $dev (Dahdi::Hardware->device_list) {
		next unless $dev->is_astribank;
		next unless $dev->product =~ /116./;
		Dahdi::Xpp::Mpp->mpp_addinfo($dev);
		push(@devs, $dev);
	}
	return @devs;
}

my @usb_devices = dev_list();

if($ARGV[0] eq 'status') {
	tws_show(@usb_devices);
} elsif($ARGV[0] eq 'jump') {
	tws_jump(@usb_devices);
} elsif($ARGV[0] eq 'disable-wd') {
	tws_watchdog(0, @usb_devices);
} elsif($ARGV[0] eq 'enable-wd') {
	tws_watchdog(1, @usb_devices);
} elsif($ARGV[0] eq 'ports') {
	tws_showports(@usb_devices);
}

__END__
