268 lines
6.2 KiB
Plaintext
268 lines
6.2 KiB
Plaintext
|
#! /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$
|
||
|
#
|
||
|
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;
|
||
|
|
||
|
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||
|
$main::VERSION = '$Id$';
|
||
|
|
||
|
sub HELP_MESSAGE() {
|
||
|
eval(usage());
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
eval {
|
||
|
$mppinfo->mpp_jump;
|
||
|
};
|
||
|
warn $@ if $@;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
} else {
|
||
|
usage;
|
||
|
}
|
||
|
|
||
|
__END__
|
||
|
|
||
|
=head1 NAME
|
||
|
|
||
|
twinstar - Control the Twinstar feature of a Xorcom Astribank
|
||
|
|
||
|
=head1 SYNOPSIS
|
||
|
|
||
|
twinstar {status|jump|enable-wd|disable-wd|ports}
|
||
|
|
||
|
=head1 DESCRIPTION
|
||
|
|
||
|
B<twinstar> is a tool to control the Twinstar (dual USB port) of a
|
||
|
Xorcom Astribank. There is a single and mandatory argument which is the
|
||
|
command to run. That command operates on all the Astribanks connected to
|
||
|
the system.
|
||
|
|
||
|
Technically all the commands are implemented using Dahdi::Xpp::Mpp which
|
||
|
in turn uses astribank_tool. Thus using thus tool will require root
|
||
|
permissions or otherwise read/write permissions to the USB device.
|
||
|
|
||
|
The twinstar may be in I<watchdog mode>, which means that it will jump
|
||
|
to the remote host if it loses contact with the local host. This can
|
||
|
happen if the machine is powered down or hangs or even if the xpp
|
||
|
drivers are unloaded. Which is why the standard twinstar scripts put the
|
||
|
Astribanks in twinstar mode on startup and remove it on normal shutdown.
|
||
|
|
||
|
An Astribank will only jump to the other host (either if asked
|
||
|
explicitly or by the watchdog) only if there is a different Astribank
|
||
|
connected to the other port and running. Which is why all of this has no
|
||
|
effect on systems that don't need this functionality.
|
||
|
|
||
|
The command are:
|
||
|
|
||
|
=head2 status
|
||
|
|
||
|
Shows the current status of all Astribanks. Note that it only shows
|
||
|
Astribanks whose current active USB port is the one connected to this
|
||
|
computer.
|
||
|
|
||
|
Example output:
|
||
|
|
||
|
DEVICE PORT WATCHDOG POWER0 POWER1
|
||
|
usb:001/010 0 on yes yes
|
||
|
usb:001/011 0 on yes yes
|
||
|
|
||
|
For each Astribank on the system that has Twinstar support we get:
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item Device
|
||
|
|
||
|
The address of the device. This is the bus address, e.g. the address you
|
||
|
see in lsusb / dahdi_hardware.
|
||
|
|
||
|
=item Port
|
||
|
|
||
|
The active USB port on the Astribank. This should be always '0' on the
|
||
|
master and always 1 on the slave.
|
||
|
|
||
|
=item Watchdog
|
||
|
|
||
|
I<on> if the watchdog is triggered in the Atribank or I<off> otherwise.
|
||
|
|
||
|
=item Power0, Power1
|
||
|
|
||
|
Shows which ports of this Astribank are connected to a USB port of a
|
||
|
running computer. This only shows whether or not the USB host provides
|
||
|
power.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head2 ports
|
||
|
|
||
|
Shows the same 'Port' column of the B<status> command.
|
||
|
|
||
|
=head2 jump
|
||
|
|
||
|
Command all the Astribanks to jump to the other port. This works
|
||
|
regardless the watchdog mode is enabled or not. But requires that there
|
||
|
is power on the other port.
|
||
|
|
||
|
=head2 enable-wd
|
||
|
|
||
|
Enables watchdog mode.
|
||
|
|
||
|
=head2 disable-wd
|
||
|
|
||
|
Disables watchdog mode.
|
||
|
|
||
|
=head1 FILES
|
||
|
|
||
|
B<twinstar> mostly uses astribank_tool which in turn mostly uses USB
|
||
|
files under /dev/bus/usb .
|
||
|
|