2010-08-18 21:49:24 +08:00
|
|
|
package Dahdi::Xpp::Xbus;
|
|
|
|
#
|
|
|
|
# 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 Dahdi::Utils;
|
|
|
|
use Dahdi::Hardware;
|
|
|
|
use Dahdi::Xpp::Xpd;
|
|
|
|
|
|
|
|
sub xpds($) {
|
|
|
|
my $xbus = shift;
|
|
|
|
return @{$xbus->{XPDS}};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub by_number($) {
|
|
|
|
my $busnumber = shift;
|
|
|
|
die "Missing xbus number parameter" unless defined $busnumber;
|
|
|
|
my @xbuses = Dahdi::Xpp::xbuses();
|
|
|
|
|
|
|
|
my ($xbus) = grep { $_->num == $busnumber } @xbuses;
|
|
|
|
return $xbus;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub by_label($) {
|
|
|
|
my $label = shift;
|
|
|
|
die "Missing xbus label parameter" unless defined $label;
|
|
|
|
my @xbuses = Dahdi::Xpp::xbuses();
|
|
|
|
|
|
|
|
my ($xbus) = grep { $_->label eq $label } @xbuses;
|
|
|
|
return $xbus;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub get_xpd_by_number($$) {
|
|
|
|
my $xbus = shift;
|
|
|
|
my $xpdid = shift;
|
|
|
|
die "Missing XPD id parameter" unless defined $xpdid;
|
|
|
|
$xpdid = sprintf("%02d", $xpdid);
|
|
|
|
my @xpds = $xbus->xpds;
|
|
|
|
my ($wanted) = grep { $_->id eq $xpdid } @xpds;
|
|
|
|
return $wanted;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub xbus_getattr($$) {
|
|
|
|
my $xbus = shift || die;
|
|
|
|
my $attr = shift || die;
|
|
|
|
$attr = lc($attr);
|
2012-03-16 04:32:27 +08:00
|
|
|
my $file = sprintf "%s/%s", $xbus->sysfs_dir, $attr;
|
2010-08-18 21:49:24 +08:00
|
|
|
|
|
|
|
open(F, $file) || die "Failed opening '$file': $!";
|
|
|
|
my $val = <F>;
|
|
|
|
close F;
|
|
|
|
chomp $val;
|
|
|
|
return $val;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub read_attrs() {
|
|
|
|
my $xbus = shift || die;
|
|
|
|
my @attrnames = qw(CONNECTOR LABEL STATUS);
|
|
|
|
my @attrs;
|
|
|
|
|
|
|
|
foreach my $attr (@attrnames) {
|
|
|
|
my $val = xbus_getattr($xbus, $attr);
|
|
|
|
if($attr eq 'STATUS') {
|
|
|
|
# Some values are in all caps as well
|
|
|
|
$val = uc($val);
|
|
|
|
} elsif($attr eq 'CONNECTOR') {
|
|
|
|
$val =~ s/^/@/; # Add prefix
|
|
|
|
} elsif($attr eq 'LABEL') {
|
|
|
|
# Fix badly burned labels.
|
|
|
|
$val =~ s/[[:^print:]]/_/g;
|
|
|
|
}
|
|
|
|
$xbus->{$attr} = $val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub transport_type($$) {
|
|
|
|
my $xbus = shift || die;
|
|
|
|
my $xbus_dir = shift;
|
|
|
|
my $transport = "$xbus_dir/transport";
|
|
|
|
if(-e "$transport/ep_00") { # It's USB
|
|
|
|
$xbus->{TRANSPORT_TYPE} = 'USB';
|
|
|
|
} else {
|
|
|
|
warn "Unkown transport in $xbus_dir\n";
|
|
|
|
undef $xbus->{TRANSPORT_TYPE};
|
|
|
|
}
|
|
|
|
return $xbus->{TRANSPORT_TYPE};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub read_xpdnames($) {
|
2012-03-16 04:32:27 +08:00
|
|
|
my $xbus_dir = shift or die;
|
|
|
|
my $pat = sprintf "%s/[0-9][0-9]:[0-9]:[0-9]", $xbus_dir;
|
2010-08-18 21:49:24 +08:00
|
|
|
my @xpdnames;
|
|
|
|
|
2012-03-16 04:32:27 +08:00
|
|
|
#printf STDERR "read_xpdnames(%s): $pat\n", $xbus_dir;
|
2010-08-18 21:49:24 +08:00
|
|
|
foreach (glob $pat) {
|
|
|
|
die "Bad /sys entry: '$_'" unless m/^.*\/([0-9][0-9]):([0-9]):([0-9])$/;
|
|
|
|
my ($busnum, $unit, $subunit) = ($1, $2, $3);
|
|
|
|
my $name = sprintf("%02d:%1d:%1d", $1, $2, $3);
|
|
|
|
#print STDERR "\t> $_ ($name)\n";
|
|
|
|
push(@xpdnames, $name);
|
|
|
|
}
|
|
|
|
return @xpdnames;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:32:27 +08:00
|
|
|
sub read_num($) {
|
|
|
|
my $self = shift or die;
|
|
|
|
my $xbus_dir = $self->sysfs_dir;
|
2013-12-30 21:09:28 +08:00
|
|
|
$xbus_dir =~ /.*-(\d\d)$/;
|
2012-03-16 04:32:27 +08:00
|
|
|
return $1;
|
|
|
|
}
|
|
|
|
|
2010-08-18 21:49:24 +08:00
|
|
|
sub new($$) {
|
|
|
|
my $pack = shift or die "Wasn't called as a class method\n";
|
2012-03-16 04:32:27 +08:00
|
|
|
my $parent_dir = shift or die;
|
|
|
|
my $entry_dir = shift or die;
|
|
|
|
my $xbus_dir = "$parent_dir/$entry_dir";
|
|
|
|
my $self = {};
|
2010-08-18 21:49:24 +08:00
|
|
|
bless $self, $pack;
|
2012-03-16 04:32:27 +08:00
|
|
|
$self->{SYSFS_DIR} = $xbus_dir;
|
|
|
|
my $num = $self->read_num;
|
|
|
|
$self->{NUM} = $num;
|
|
|
|
$self->{NAME} = "XBUS-$num";
|
2010-08-18 21:49:24 +08:00
|
|
|
$self->read_attrs;
|
|
|
|
# Get transport related info
|
|
|
|
my $transport = "$xbus_dir/transport";
|
2012-03-16 04:32:27 +08:00
|
|
|
die "OLD DRIVER: missing '$transport'\n" unless -e $transport;
|
2010-08-18 21:49:24 +08:00
|
|
|
my $transport_type = $self->transport_type($xbus_dir);
|
|
|
|
if(defined $transport_type) {
|
|
|
|
my $tt = "Dahdi::Hardware::$transport_type";
|
|
|
|
my $hw = $tt->set_transport($self, $xbus_dir);
|
|
|
|
#printf STDERR "Xbus::new transport($transport_type): %s\n", $hw->{HARDWARE_NAME};
|
|
|
|
}
|
|
|
|
my @xpdnames;
|
|
|
|
my @xpds;
|
2012-03-16 04:32:27 +08:00
|
|
|
@xpdnames = read_xpdnames($self->sysfs_dir);
|
2010-08-18 21:49:24 +08:00
|
|
|
foreach my $xpdstr (@xpdnames) {
|
2012-03-16 04:32:27 +08:00
|
|
|
my $xpd = Dahdi::Xpp::Xpd->new($self, $xpdstr);
|
2010-08-18 21:49:24 +08:00
|
|
|
push(@xpds, $xpd);
|
|
|
|
}
|
|
|
|
@{$self->{XPDS}} = sort { $a->id <=> $b->id } @xpds;
|
|
|
|
return $self;
|
|
|
|
}
|
|
|
|
|
2014-04-07 02:33:12 +08:00
|
|
|
sub dahdi_registration($$) {
|
|
|
|
my $xbus = shift;
|
|
|
|
my $on = shift;
|
|
|
|
my $result;
|
|
|
|
my $file = sprintf("%s/dahdi_registration", $xbus->sysfs_dir);
|
|
|
|
# Handle old drivers without dahdi_registration xbus attribute
|
|
|
|
if (! -f $file) {
|
|
|
|
warn "Old xpp driver without dahdi_registration support. Emulating it using xpd/span support\n";
|
|
|
|
my @xpds = sort { $a->id <=> $b->id } $xbus->xpds();
|
|
|
|
my $prev;
|
|
|
|
foreach my $xpd (@xpds) {
|
|
|
|
$prev = $xpd->dahdi_registration($on);
|
|
|
|
}
|
|
|
|
return $prev;
|
|
|
|
}
|
|
|
|
# First query
|
|
|
|
open(F, "$file") or die "Failed to open $file for reading: $!";
|
|
|
|
$result = <F>;
|
|
|
|
chomp $result;
|
|
|
|
close F;
|
|
|
|
if(defined($on) and $on ne $result) { # Now change
|
|
|
|
open(F, ">$file") or die "Failed to open $file for writing: $!";
|
|
|
|
print F ($on)?"1":"0";
|
|
|
|
if(!close(F)) {
|
|
|
|
if($! == 17) { # EEXISTS
|
|
|
|
# good
|
|
|
|
} else {
|
|
|
|
undef $result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2010-08-18 21:49:24 +08:00
|
|
|
sub pretty_xpds($) {
|
|
|
|
my $xbus = shift;
|
|
|
|
my @xpds = sort { $a->id <=> $b->id } $xbus->xpds();
|
|
|
|
my @xpd_types = map { $_->type } @xpds;
|
|
|
|
my $last_type = '';
|
|
|
|
my $mult = 0;
|
|
|
|
my $xpdstr = '';
|
|
|
|
foreach my $curr (@xpd_types) {
|
|
|
|
if(!$last_type || ($curr eq $last_type)) {
|
|
|
|
$mult++;
|
|
|
|
} else {
|
|
|
|
if($mult == 1) {
|
|
|
|
$xpdstr .= "$last_type ";
|
|
|
|
} elsif($mult) {
|
|
|
|
$xpdstr .= "$last_type*$mult ";
|
|
|
|
}
|
|
|
|
$mult = 1;
|
|
|
|
}
|
|
|
|
$last_type = $curr;
|
|
|
|
}
|
|
|
|
if($mult == 1) {
|
|
|
|
$xpdstr .= "$last_type ";
|
|
|
|
} elsif($mult) {
|
|
|
|
$xpdstr .= "$last_type*$mult ";
|
|
|
|
}
|
|
|
|
$xpdstr =~ s/\s*$//; # trim trailing space
|
|
|
|
return $xpdstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|