[dahdi-commits] tzafrir: branch tools/tzafrir/sysfs r8654 - in /tools/team/tzafrir/sysfs: ./ ...

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Mon May 17 17:27:20 CDT 2010


Author: tzafrir
Date: Mon May 17 17:27:16 2010
New Revision: 8654

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8654
Log:
system.conf: allow using names instead of numbers

* Names: pathes relatice to /dev/dahdi
* dahdi_cfg -p: show pathes of channels (type of verbosity).
* Supported for channel "numbers" and for span "numbers".
* dahdi_genconf can generate configuration with names.
* Radio ("channel[s]") not supported with names yet, though.
* 'lsdahdi -p' - also prints the pool name of each channel.

Dahdi-perl:
channo_range, bchan_range etc. moved from Dahdi::Config::Gen to Dahdi::Utils.

Added:
    tools/team/tzafrir/sysfs/xpp/chan_pools.sample   (with props)
Modified:
    tools/team/tzafrir/sysfs/dahdi_cfg.c
    tools/team/tzafrir/sysfs/xpp/Makefile
    tools/team/tzafrir/sysfs/xpp/dahdi_pools
    tools/team/tzafrir/sysfs/xpp/dahdi_spanmap
    tools/team/tzafrir/sysfs/xpp/lsdahdi
    tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Chans.pm
    tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen.pm
    tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
    tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/System.pm
    tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Pool.pm
    tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Span.pm
    tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Utils.pm

Modified: tools/team/tzafrir/sysfs/dahdi_cfg.c
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/dahdi_cfg.c?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/dahdi_cfg.c (original)
+++ tools/team/tzafrir/sysfs/dahdi_cfg.c Mon May 17 17:27:16 2010
@@ -33,7 +33,10 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/param.h>
 #include <fcntl.h>
 #include <errno.h>
 
@@ -104,6 +107,8 @@
 static int force = 0;
 
 static int stopmode = 0;
+
+static int showpaths = 0;
 
 static int numdynamic = 0;
 
@@ -129,6 +134,10 @@
 	"Mu-law",
 	"A-law"
 };
+
+static int	path_channels;
+static char	*chan_pathnames[DAHDI_MAX_CHANNELS];
+static int	chan_indexes[DAHDI_MAX_CHANNELS];
 
 static const char *sigtype_to_str(const int sig)
 {
@@ -391,6 +400,29 @@
 	return 0;
 }
 
+static int path2channo(const char *relative_path, int relative_index)
+{
+	char		path[PATH_MAX];
+	struct stat	stbuf;
+	int		channo;
+
+	if(!relative_path)
+		return relative_index;	/* identify map */
+	//fprintf(stderr, "DEBUG: %s!%d\n", relative_path, relative_index);
+	snprintf(path, sizeof(path), "/dev/dahdi/%s/%d", relative_path, relative_index);
+	if (stat(path, &stbuf) < 0) {
+		perror(path);
+		exit(-1);
+	}
+	if (! S_ISCHR(stbuf.st_mode)) {
+		fprintf(stderr, "%s is not a character device\n", path);
+		exit(-1);
+	}
+	channo = minor(stbuf.st_rdev);
+	path_channels++;
+	return channo;
+}
+
 int apply_channels(int chans[], char *argstr)
 {
 	char *args[DAHDI_MAX_CHANNELS+1];
@@ -399,6 +431,18 @@
 	int chan;
 	int start, finish;
 	char argcopy[256];
+	char *pname;
+
+	pname = strtok(argstr, "!");
+	if (pname) {
+		argstr += strlen(pname) + 1;
+		if(argstr[0] == '\0') {
+			argstr = pname;
+			pname = NULL;
+		} else {
+			pname = strdup(pname);
+		}
+	}
 	res = parseargs(argstr, args, DAHDI_MAX_CHANNELS, ',');
 	if (res < 0) {
 		error("Too many arguments...  Max is %d\n", DAHDI_MAX_CHANNELS);
@@ -433,9 +477,16 @@
 				error("Range '%s' should start before it ends\n", args[x]);
 				return -1;
 			}
-			for (y=start;y<=finish;y++)
-				chans[y]=1;
+			for (y=start;y<=finish;y++) {
+				int realchan = path2channo(pname, y);
+				chans[realchan]=1;
+				chan_pathnames[realchan] = pname;
+				chan_indexes[realchan] = y;
+				//fprintf(stderr, "DEBUG: %s\t%d -> %d\n", pname, y, realchan);
+			}
 		} else {
+			int	realchan;
+
 			/* It's a single channel */
 			res2 =sscanf(args[x], "%i", &chan);
 			if (res2 != 1) {
@@ -445,8 +496,12 @@
 				error("Channel must be between 1 and %d (not '%d')\n", DAHDI_MAX_CHANNELS - 1, chan);
 				return -1;
 			}
-			chans[chan]=1;
-		}		
+			realchan = path2channo(pname, chan);
+			chans[realchan]=1;
+			chan_pathnames[realchan] = pname;
+			chan_indexes[realchan] = chan;
+			//fprintf(stderr, "DEBUG: %s\t%d -> %d\n", pname, chan, realchan);
+		}
 	}
 	return res;
 }
@@ -713,14 +768,14 @@
 	unsigned int x;
 
 	echocan = strtok(args, ",");
-
-	while ((chanlist = strtok(NULL, ","))) {
-		res = apply_channels(chans, chanlist);
-		if (res <= 0) {
-			return -1;
-		}
-	}
-
+	if (!echocan) {
+		return -1;
+	}
+	chanlist = args + strlen(args) + 1;
+	res = apply_channels(chans, chanlist);
+	if (res <= 0) {
+		return -1;
+	}
 	for (x = 0; x < DAHDI_MAX_CHANNELS; x++) {
 		if (chans[x]) {
 			dahdi_copy_string(ae[x].echocan, echocan, sizeof(ae[x].echocan));
@@ -1235,16 +1290,26 @@
 		printf("Dynamic span %d: driver %s, addr %s, channels %d, timing %d\n",
 		       x +1, zds[x].driver, zds[x].addr, zds[x].numchans, zds[x].timing);
 	}
-	if (verbose > 1) {
+	if (verbose > 1 || showpaths) {
 		printf("\nChannel map:\n\n");
 		for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+			char	channame[BUFSIZ];
+
+			if(showpaths) {
+				y = chan_indexes[x];
+				snprintf(channame, sizeof(channame), "%s!%02d",
+					(chan_pathnames[x]) ? chan_pathnames[x] : "<NOPOOL>", y);
+			} else {
+				y = x;
+				snprintf(channame, sizeof(channame), "%02d", y);
+			}
 			if ((cc[x].sigtype != DAHDI_SIG_SLAVE) && (cc[x].sigtype)) {
 				configs++;
 				ps = 0;
 				if ((cc[x].sigtype & __DAHDI_SIG_DACS) == __DAHDI_SIG_DACS)
-					printf("Channel %02d %s to %02d", x, sig[x], cc[x].idlebits);
+					printf("Channel %-15s %s to %02d", channame, sig[x], cc[x].idlebits);
 				else {
-					printf("Channel %02d: %s (%s)", x, sig[x], laws[cc[x].deflaw]);
+					printf("Channel %-15s %s (%s)", channame, sig[x], laws[cc[x].deflaw]);
 					printf(" (Echo Canceler: %s)", ae[x].echocan[0] ? ae[x].echocan : "none");
 					for (y=1;y<DAHDI_MAX_CHANNELS;y++) {
 						if (cc[y].master == x)  {
@@ -1367,7 +1432,7 @@
 	char *key, *value;
 	int x,found;
 
-	while((c = getopt(argc, argv, "fthc:vsd::")) != -1) {
+	while((c = getopt(argc, argv, "fthc:vsd::p")) != -1) {
 		switch(c) {
 		case 'c':
 			filename=optarg;
@@ -1396,6 +1461,9 @@
 			else
 				debug = 1;	
 			break;
+		case 'p':
+			showpaths = 1;
+			break;
 		}
 	}
 	
@@ -1455,7 +1523,7 @@
 		fprintf(stderr, "\n%d error(s) detected\n\n", errcnt);
 		exit(1);
 	}
-	if (verbose) {
+	if (verbose || showpaths) {
 		printconfig(fd);
 	}
 	if (!fo_real) 
@@ -1506,6 +1574,11 @@
 		if (!cc[x].sigtype)
 			continue;
 		
+		if (path_channels && !chan_pathnames[x]) {
+			fprintf(stderr,
+				"Warning: Channel %d has no associated path (%d others have)\n",
+				x, path_channels);
+		}
 		if (!needupdate) {
 			memset(&current_state, 0, sizeof(current_state));
 			current_state.channo = cc[x].chan | DAHDI_GET_PARAMS_RETURN_MASTER;

Modified: tools/team/tzafrir/sysfs/xpp/Makefile
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/Makefile?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/Makefile (original)
+++ tools/team/tzafrir/sysfs/xpp/Makefile Mon May 17 17:27:16 2010
@@ -50,6 +50,7 @@
 		dahdi_genconf	\
 		dahdi_hardware	\
 		dahdi_pools	\
+		dahdi_spanmap	\
 		twinstar	\
 		#
 

Added: tools/team/tzafrir/sysfs/xpp/chan_pools.sample
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/chan_pools.sample?view=auto&rev=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/chan_pools.sample (added)
+++ tools/team/tzafrir/sysfs/xpp/chan_pools.sample Mon May 17 17:27:16 2010
@@ -1,0 +1,55 @@
+#
+# This is a configuration file for dahdi_pools(8)
+#
+# It orders group of channels into named "pools" that can
+# later be referenced by dahdi_cfg(8) and asterisk(8)
+# Identifiers for this file may be obtained via dahdi_spanmap(1)
+#
+# Each (non-comment or empty) contains a pool name and a pool value.
+#
+# Pool names: alphanumeric identifiers (may also contain '-').
+#
+# Pool values:
+# * Pool channels are taken from ordered, whitespace separated list of
+#   components. 
+# * Each component may specify:
+#   - A hardware device (via "Hardware ID")
+#   - An optional list of channels in a parenthesis
+# * Parenthesised channel list:
+#   - Parts separated by semicolon (;)
+#   - Each part may contain a "Span ID"
+#   - Optionally, the "Span ID" may be suffixed with "!<chan_spec>" to
+#     select only some channels from this span.
+# * A chan_spec:
+#   - Just like in /etc/dahdi/system.conf and /etc/asterisk/chan_dahdi.conf
+#   - A comma separated list of channel ranges.
+#   - Each range is specified as "<n>-<m>" or a single number "<m>"
+# * Globs ('*', '?', '[...]') may be used for "Hardware ID" and "Span ID" 
+#
+# Examples. Select channels:
+#
+#	# All from a specific hardware device
+#	wildcard	@PCI_Bus_01_Slot_10
+#
+#	# All from two spans belonging to a hardware device
+#	bris-A		usb:QA-04(02;03)
+#
+#	# Some spans from one hardware device + all spans from another
+#	bris-B		usb:QA-04(00;01) @PCI_Bus_01_Slot_11
+#	# Same, but using globs ('*', '?', '[...]')
+#	bris-B		usb:QA-04(0[01]) @PCI_Bus_01_Slot_11
+#
+#	# The whole shee-bang: Select specific channels from different
+#       # Spans of different hardware devices
+#	fxses		@PCI_Bus_01_Slot_12(00!4) usb:QA-04([1-3]0) usb:QA-1(00!1-8)
+#	outputs		usb:QA-1(00!9;00!10)
+#	inputs		usb:QA-1(00!11-14)
+#	fxos		@PCI_Bus_01_Slot_12(00!3) usb:QA-1(10)
+
+wildcard	@PCI_Bus_01_Slot_10
+fxses		@PCI_Bus_01_Slot_12(00!4) usb:QA-04([1-3]0) usb:QA-1(00!1-8)
+outputs		usb:QA-1(00!9;00!10)
+inputs		usb:QA-1(00!11-14)
+bris-A		usb:QA-04(02;03)
+bris-B		usb:QA-04(0[01]) @PCI_Bus_01_Slot_11
+fxos		@PCI_Bus_01_Slot_12(00!3) usb:QA-1(10)

Propchange: tools/team/tzafrir/sysfs/xpp/chan_pools.sample
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tools/team/tzafrir/sysfs/xpp/chan_pools.sample
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: tools/team/tzafrir/sysfs/xpp/chan_pools.sample
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tools/team/tzafrir/sysfs/xpp/dahdi_pools
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/dahdi_pools?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/dahdi_pools (original)
+++ tools/team/tzafrir/sysfs/xpp/dahdi_pools Mon May 17 17:27:16 2010
@@ -20,10 +20,28 @@
 	die "$0: Failed creating '$dir' (status $?)" if $?;
 }
 
-sub remove_tree($) {
-	my $dir = shift || die;
-	system("rm -rf -- '$dir'");
-	die "$0: Failed removing '$dir' (status $?)" if $?;
+sub remove_tree() {
+	print STDERR "Removing '$poolbase'\n";
+	system("rm -rf -- '$poolbase'");
+	die "$0: Failed removing '$poolbase' (status $?)" if $?;
+}
+
+sub list_pools() {
+	my @pools = glob "$poolbase/*";
+	foreach my $p (sort @pools) {
+		my @links = glob "$p/*";
+		printf "%s:\n", map { s|^.*/||; $_; } $p;
+		next unless @links;
+		my @chans = @links;
+		map { s|^.*/||; $_; } @chans;
+		my %chanmap;
+		@chanmap{@chans} = @links;
+		foreach my $c (sort { $a <=> $b } @chans) {
+			my $l = readlink $chanmap{$c};
+			$l =~ s,/dev/dahdi/spans/,,;
+			print "\t$c\t-> $l\n";
+		}
+	}
 }
 
 sub process_pool($) {
@@ -34,23 +52,31 @@
 	return unless @entries;
 	make_path "$destdir";
 	foreach (@entries) {
-		my $device = $_->{DEVICE};
+		my $devfile = $_->{DEVFILE};
 		my $dest = $_->{DEST};
-		symlink($device, $dest) || die "$0: Failed symlink($device, $dest): $!\n";
-		#print STDERR "symlink($device, $dest)\n";
+		symlink($devfile, $dest) || die "$0: Failed symlink($devfile, $dest): $!\n";
+		#print STDERR "symlink($devfile, $dest)\n";
 	}
 }
 
-my $mode = shift || die "Usage: $0 {create|delete}\n";
+sub usage() {
+	die "Usage: $0 {list|create|delete}\n";
+}
+
+my $mode = shift || usage;
 
 if($mode eq 'create') {
 	my @pools = Dahdi::Pool->get_pools;
-	remove_tree($poolbase);
+	remove_tree();
 	foreach my $pool (@pools) {
 		process_pool($pool);
 	}
 } elsif($mode eq 'delete') {
-	remove_tree($poolbase);
+	remove_tree();
+} elsif($mode eq 'list') {
+	list_pools;
+} else {
+	usage;
 }
 
 __END__

Modified: tools/team/tzafrir/sysfs/xpp/dahdi_spanmap
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/dahdi_spanmap?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/dahdi_spanmap (original)
+++ tools/team/tzafrir/sysfs/xpp/dahdi_spanmap Mon May 17 17:27:16 2010
@@ -14,6 +14,7 @@
 
 use Dahdi;
 use Dahdi::Span;
+use Dahdi::Pool;
 use Dahdi::Xpp;
 use Dahdi::Xpp::Xbus;
 use Dahdi::Hardware;
@@ -30,13 +31,13 @@
 my @devices = Dahdi::Hardware->device_list;
 my @spans = Dahdi::spans;
 
-my $format = "%-3s %-20s %-30s %-20s %-4s %s\n";
+my $format = "%-3s %-20s %-25s %-18s %-10s %s\n";
 
-printf $format, "#", "Name", "Location", "Hardware ID", "Port", "Type";
+printf $format, "#", "Name", "Location", "Hardware ID", "Span ID", "Type";
 foreach my $span (sort { $a->num <=> $b->num } @spans) {
 	printf $format,
 		(0+$span->num), $span->name, $span->location, $span->hardware_id,
-		$span->hardware_port, $span->spantype;
+		$span->span_id, $span->spantype;
 }
 
 __END__
@@ -61,10 +62,10 @@
 serial number or a similar unique identifier of the device contaning the
 span. Though currently most drivers don't provide it.
 
-I<Port> is an identifier of the port contaning this span in the device.
+I<Span ID> is an identifier of the span in the device.
 
-The combination of (I<location>, I<port>) should be a unique identifier of
-the span. Likewise (I<hardware_id>, I<port>), if the I<hardware_id> is set.
+The combination of (I<location>, I<span_id>) should be a unique identifier of
+the span. Likewise (I<hardware_id>, I<span_id>), if the I<hardware_id> is set.
 
 Example output:
 
@@ -93,7 +94,7 @@
 =head1 FILES
 
 The information is based on properties of the spans under
-F</sys/bus/astribanks/devices>.
+F</sys/bus/dahdi_spans/devices>.
 
 =head1 SEE ALSO
 

Modified: tools/team/tzafrir/sysfs/xpp/lsdahdi
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/lsdahdi?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/lsdahdi (original)
+++ tools/team/tzafrir/sysfs/xpp/lsdahdi Mon May 17 17:27:16 2010
@@ -11,11 +11,15 @@
 use File::Basename;
 BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); }
 
+use Getopt::Std;
 use Dahdi;
 use Dahdi::Span;
 use Dahdi::Xpp;
 use Dahdi::Xpp::Xbus;
 use Dahdi::Xpp::Xpd;
+
+my %opts;
+getopts('p', \%opts) || die "Usage: $0 [-p]\n";
 
 my @xbuses = Dahdi::Xpp::xbuses;
 my @xpds = map { $_->xpds } @xbuses;
@@ -38,8 +42,14 @@
 		$batt = "(battery)" if $chan->battery;
 		my @alarms = $chan->alarms;
 		my $alarm_str = join(" ", @alarms);
-		printf "%3d %-10s %-10s %s %s %s\n",
-			$chan->num, $type, $chan->signalling, $chan->info, $batt, $alarm_str;
+		my $chanstr;
+		if($opts{'p'}) {
+			$chanstr = sprintf "%3d %-15s", $chan->num, $chan->poolstr;
+		} else {
+			$chanstr = sprintf "%3d", $chan->num;
+		}
+		printf "%s %-10s %-10s %s %s %s\n",
+			$chanstr, $type, $chan->signalling, $chan->info, $batt, $alarm_str;
 		$index++;
 	}
 }

Modified: tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Chans.pm
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Chans.pm?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Chans.pm (original)
+++ tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Chans.pm Mon May 17 17:27:16 2010
@@ -174,6 +174,12 @@
 	return $type;
 }
 
+sub poolstr() {
+	my $chan = shift || die;
+	my $span = $chan->span;
+	return $span->map_channel_range($chan);
+}
+
 sub new($$$) {
 	my $pack = shift or die "Wasn't called as a class method\n";
 	my $span = shift or die "Missing a span parameter\n";
@@ -190,14 +196,6 @@
 	$self->{DEV} = $self->_get_dev_attr('dev');
 	$self->{INDEX} = $self->_get_dev_attr('chanpos');
 	$self->{FQN} = $self->_get_dev_attr('name'); # TODO: correct?
-	my $poolentry = Dahdi::Pool->dev2poolentry($self->{DEV});
-	if(defined $poolentry) {
-		$self->{POOLPOS} = $poolentry->{NUM};
-		$span->{SUBDIR} = $poolentry->{SUBDIR} unless defined $span->{SUBDIR};
-		my $pool = $poolentry->{POOL};
-		$span->{POOLNAME} = $pool->{NAME} unless defined $span->{POOLNAME};
-	}
-
 	$self->{ALARMS} = [];
 	my $alarms = $self->_get_dev_attr('alarms');
 	if ($alarms) {$self->{ALARMS} = [$alarms]}

Modified: tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen.pm
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen.pm?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen.pm (original)
+++ tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen.pm Mon May 17 17:27:16 2010
@@ -47,70 +47,14 @@
 @EXPORT_OK = qw(is_true);
 
 use strict;
+use Dahdi::Pool;
+use Dahdi::Utils;
 
 # Parse values as true/false 
 sub is_true($) {
 	my $val = shift;
 	return undef unless defined $val;
 	return $val =~ /^(1|y|yes)$/i;
-}
-
-sub range_string($$) {
-	my ($start, $end) = @_;
-
-	if($start == $end) {
-		sprintf "%d", $start;
-	} else {
-		sprintf "%d-%d", $start, $end;
-	}
-}
-
-# Generate channel range strings from arrays of chan numbers
-# E.g: "63-77,79-93"
-sub channo_range(@) {
-	my @channos = sort { $a <=> $b } @_;
-	my $first_num = $channos[0];
-	my $range_start = $first_num;
-	my @range;
-	my $prev = undef;
-
-	foreach my $c (@channos) {
-		my $curr = $c;
-		if(!defined($prev)) {
-			# First iteration
-			$prev = $curr;
-		} elsif($curr != $prev + 1) {
-			# New range
-			push(@range, range_string($range_start, $prev));
-			$range_start = $curr;
-		}
-		$prev = $curr;
-	}
-	if($prev >= $first_num) {
-		# Last range
-		push(@range, range_string($range_start, $prev));
-	}
-	return join(',', @range);
-}
-
-# Generate channel range strings from chan objects
-# E.g: "63-77,79-93"
-sub chan_range(@) {
-	my @chans = sort { $a->num <=> $b->num } @_;
-	my @channos = map { $_->num } @chans;
-	channo_range(@channos);
-}
-
-# Generate channel range strings from digital span objects
-# E.g: "63-77,79-93"
-sub bchan_range($) {
-	my $span = shift || die;
-	die unless $span->is_digital();
-	my $first_chan = ($span->chans())[0];
-	my $first_num = $first_chan->num();
-	my $bchan_ref = $span->bchan_list();
-	my @channos = map { $_ + $first_num } @{$bchan_ref};
-	channo_range(@channos);
 }
 
 # Returns a channel numbers array from a channel range string

Modified: tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm (original)
+++ tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm Mon May 17 17:27:16 2010
@@ -2,6 +2,9 @@
 use strict;
 
 use Dahdi::Config::Gen qw(is_true);
+use Dahdi::Pool;
+
+my @pools = Dahdi::Pool->get_pools;
 
 sub new($$$) {
 	my $pack = shift || die;
@@ -57,7 +60,7 @@
 	my $context = $gconfig->{'context'}{"$faketype"};
 	die "$0: missing default context\n" unless $context;
 	my @to_reset = qw/context group/;
-	my $chans = Dahdi::Config::Gen::bchan_range($span);
+	my $chans = $span->bchan_range();
 	$group .= "," . (10 + $num);	# Invent unique group per span
 	my $country = $gconfig->{'loadzone'};
 	my @valid_countries = qw( ar br cn cz co ec itu mx ph ve );
@@ -150,18 +153,19 @@
 	printf "context=$context\n";
 	printf "switchtype = %s\n", $span->switchtype;
 	printf "signalling = %s\n", $sig;
-	printf "channel => %s\n", Dahdi::Config::Gen::bchan_range($span);
+	printf "channel => %s\n", $span->bchan_range();
 	reset_chandahdi_values(@to_reset);
 }
 
 sub gen_channel($$) {
 	my $self = shift || die;
 	my $chan = shift || die;
+	my $span = $chan->span;
 	my $relative_numbers = has_pool($chan->span);
 	my $gconfig = $self->{GCONFIG};
 	my $type = $chan->type;
 	my $num = $chan->num;
-	die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
+	die "channel $num type $type is not an analog channel\n" if $span->is_digital();
 	my $exten = $gconfig->{'base_exten'} + $num;
 	my $sig = $gconfig->{'chan_dahdi_signalling'}{$type};
 	my $context = $gconfig->{'context'}{$type};
@@ -172,14 +176,12 @@
 	die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig;
 	die "missing context for chan #$num type $type" unless $context;
 	my $caller_id;
-	my $pos;
-	if($relative_numbers) {
-		$pos = $chan->poolpos;
-		my $pool = $chan->span->poolname();
-		$caller_id = sprintf "\"Channel %s-%d\" <%04d>", $pool, $num, $exten;
+	my $pos = $chan->poolstr;
+	if(defined $pos) {
+		$caller_id = sprintf "\"Channel %s\" <%04d>", $pos, $exten;
 	} else {
 		$pos = $num;
-		$caller_id = sprintf "\"Channel %d\" <%04d>", $num, $exten;
+		$caller_id = sprintf "\"Channel %d\" <%04d>", $pos, $exten;
 	}
 	$caller_id = ($type eq 'FXO') ? 'asreceived' : $caller_id;
 	if($type eq 'IN') {
@@ -192,7 +194,7 @@
 	$signalling = " " . $signalling if $signalling;
 	my $info = $chan->info;
 	$info = " " . $info if $info;
-	printf ";;; line=\"%d (%d) %s%s%s\"\n", $pos, $num, $chan->fqn, $signalling, $info;
+	printf ";;; line=\"%s (%d) %s%s%s\"\n", $pos, $num, $chan->fqn, $signalling, $info;
 	printf "signalling=$sig\n";
 	printf "callerid=$caller_id\n";
 	printf "mailbox=%04d\n", $exten unless $type eq 'FXO';
@@ -201,7 +203,7 @@
 	}
 	printf "context=$context\n";
 	printf "immediate=$immediate\n" if defined $immediate;
-	printf "channel => %d\n", $pos;
+	printf "channel => %s\n", $pos;
 	# Reset following values to default
 	printf "callerid=\n";
 	printf "mailbox=\n" unless $type eq 'FXO';

Modified: tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/System.pm
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/System.pm?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/System.pm (original)
+++ tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Config/Gen/System.pm Mon May 17 17:27:16 2010
@@ -2,6 +2,7 @@
 use strict;
 
 use Dahdi::Config::Gen qw(is_true);
+use Dahdi::Pool;
 
 sub new($$$) {
 	my $pack = shift || die;
@@ -69,15 +70,16 @@
 	my $chan_range;
 	if($span->is_pri()) {
 		if ($pri_connection_type eq 'PRI') {
-			$chan_range = Dahdi::Config::Gen::bchan_range($span);
+			$chan_range = $span->bchan_range();
 			printf "bchan=%s\n", $chan_range;
-			my $dchan = $span->dchan();
-			printf "dchan=%d\n", $dchan->num();
+			my $dchan = $span->dchan_string();
+			printf "dchan=%s\n", $dchan;
 		} elsif ($pri_connection_type eq 'R2' ) {
 			my $idle_bits = $gconfig->{'r2_idle_bits'};
-			$chan_range = Dahdi::Config::Gen::bchan_range($span);
+			$chan_range = $span->bchan_range();
 			printf "cas=%s:$idle_bits\n", $chan_range;
-			printf "dchan=%d\n", $span->dchan()->num();
+			my $dchan = $span->dchan_string();
+			printf "dchan=%s\n", $dchan;
 		} elsif ($pri_connection_type eq 'CAS' ) {
 			my $type = ($termtype eq 'TE') ? 'FXO' : 'FXS';
 			my $sig = $gconfig->{'dahdi_signalling'}{$type};
@@ -155,36 +157,38 @@
 		} else {
 			$dchan_type = 'hardhdlc';
 		}
-		printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span);
-		my $dchan = $span->dchan();
-		printf "$dchan_type=%d\n", $dchan->num();
+		printf "bchan=%s\n", $span->bchan_range();
+		my $dchan = $span->dchan_string();
+		printf "$dchan_type=%s\n", $dchan;
 	} elsif($span->is_pri()) {
 		if ($gconfig->{'pri_connection_type'} eq 'PRI') {
-			printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span);
-			my $dchan = $span->dchan();
-			printf "dchan=%d\n", $dchan->num();
+			printf "bchan=%s\n", $span->bchan_range();
+			my $dchan = $span->dchan_string();
+			printf "dchan=%s\n", $dchan;
 		} elsif ($gconfig->{'pri_connection_type'} eq 'R2' ) {
 			my $idle_bits = $gconfig->{'r2_idle_bits'};
-			printf "cas=%s:$idle_bits\n", Dahdi::Config::Gen::bchan_range($span);
-			printf "dchan=%d\n", $span->dchan()->num();
+			printf "cas=%s:$idle_bits\n", $span->bchan_range();
+			my $dchan = $span->dchan_string();
+			printf "dchan=%s\n", $dchan;
 		}
 	} else {
 		die "Digital span $num is not BRI, nor PRI?";
 	}
-	print_echo_can($gconfig, Dahdi::Config::Gen::bchan_range($span));
+	print_echo_can($gconfig, $span->bchan_range());
 }
 
 sub gen_signalling($$) {
 	my $gconfig = shift || die;
 	my $chan = shift || die;
 	my $type = $chan->type;
-	my $num = $chan->num;
-
-	die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
+	my $span = $chan->span;
+
+	die "channel " . $chan->fqn . " type $type is not an analog channel\n" if $span->is_digital();
 	if($type eq 'EMPTY') {
-		printf "# channel %d, %s, no module.\n", $num, $chan->fqn;
+		printf "# channel %s, no module.\n", $chan->fqn;
 		return;
 	}
+	my $num = $span->map_channel_range($chan);
 	my $signalling = $gconfig->{'dahdi_signalling'};
 	my $sig = $signalling->{$type} || die "unknown default dahdi signalling for chan $num type $type";
 	if ($type eq 'IN') {

Modified: tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Pool.pm
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Pool.pm?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Pool.pm (original)
+++ tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Pool.pm Mon May 17 17:27:16 2010
@@ -32,36 +32,61 @@
 =cut
 
 my $cfgfile = "/etc/dahdi/chan_pools";
-my $poolbase = "/dev/dahdi/pool";
-my %devices;
+my %device_nodes;
+my @poolentry_byspanno;
 my %pools;
 my %pool_components;
 
-sub save_linkinfo($$) {
-	my $self = shift || die;
+sub file_devt($) {
 	my $devfile = shift || die;
-	my $dest = shift;
-
-	unless (-c $devfile) {
-		warn "Not a chardev";
-		next;
-	}
-	my $entries = $self->{ENTRIES};
-	my $rdev = (stat($devfile))[6];
-	#symlink($devfile, $dest) || die "$0: Failed symlink($devfile, $dest): $!\n";
+	my @fields = stat($devfile) or die "$0: stat($devfile) failed: $!";
+	my $rdev = $fields[6];
 	my $minor = $rdev & 0xFF;
 	my $major = $rdev >> 8;
 	my $devt = "$major:$minor";
-	if (defined $devices{$devt}) {
+	return $devt;
+}
+
+sub save_linkinfo($$) {
+	my $self = shift || die;
+	my $chan = shift || die;
+	my $poolidx = shift || die;
+
+	my $poolname = $self->{NAME};
+	my $dest = "/dev/dahdi/pool/$poolname/$poolidx";
+	my $span = $chan->span;
+	my $spanno = $span->num;
+	my $channo = $chan->index;
+	my $devfile = sprintf "/dev/dahdi/spans/%03d/%02d", $spanno, $channo;
+	warn "Missing '$devfile'\n" unless -c $devfile;
+	unless (-c $devfile) {
+		warn "Not a chardev";
+		return;
+	}
+	my $entries = $self->{ENTRIES};
+	my $devt = file_devt($devfile);
+	if (defined $device_nodes{$devt}) {
 		warn "$0: Duplicate '$devt' (from '$devfile')";
-		my $d = $devices{$devt};
+		my $d = $device_nodes{$devt};
 		die "POOL='$d->{SUBDIR}', DEST='$d->{DEST}'\n";
 	}
-	$devices{$devt} = {
-			DEVICE	=> $devfile,
+	$device_nodes{$devt} = {
+			POOL	=> $self,
+			POOLIDX	=> $poolidx,
+			DEVFILE	=> $devfile,
+			DEVT	=> $devt,
 			DEST	=> $dest,
+			CHAN	=> $chan,
 		};
-	push(@{$entries}, $devices{$devt});
+	if (defined $poolentry_byspanno[$spanno][$channo]) {
+		my $t = $poolentry_byspanno[$spanno][$channo];
+		printf STDERR "Already defined: %3d/%02d => %s!%d\n",
+			$spanno, $channo, $t->{POOL}{NAME}, $t->{POOLIDX};
+		printf STDERR "(try to overwrite with %s!%d\n", $poolname, $poolidx;
+		die;
+	}
+	$poolentry_byspanno[$spanno][$channo] = $device_nodes{$devt};
+	push(@{$entries}, $device_nodes{$devt});
 }
 
 sub new($$) {
@@ -70,6 +95,7 @@
 	my $components = shift || die;
 	my $self = {
 		NAME	=> $poolname,
+		POOLSTR	=> "pool/$poolname",
 		ENTRIES	=> [],
 	};
 	bless $self, $class;
@@ -98,14 +124,12 @@
 		$select_spec = '*' unless defined $select_spec;
 		my @selectors = split(/;/, $select_spec);
 		foreach my $sel (@selectors) {
-			my ($port, $chanspec) = split(/\//, $sel);
-			$chanspec = '*' unless defined $chanspec;
-			$port = Dahdi::Utils::glob2regex($port);
-			$chanspec = Dahdi::Utils::glob2regex($chanspec);
-			my @good_spans = grep { $_->hardware_port =~ /^$port$/ } @spans;
+			my ($spanid, $chanspec) = split(/!/, $sel);
+			$spanid = Dahdi::Utils::glob2regex($spanid);
+			my @good_spans = grep { $_->span_id =~ /^$spanid$/ } @spans;
 			my @good_chans;
 			foreach my $s (@good_spans) {
-				my @chans = grep { $_->index =~ /^$chanspec$/ } $s->chans;
+				my @chans = $s->chans_subset($chanspec);
 				push(@good_chans, @chans);
 			}
 			push(@selected_chans, @good_chans);
@@ -113,33 +137,42 @@
 		#print STDERR "Pool $poolname: $comp -- ", join(' ', map({ $_->fqn } @selected_chans)), "\n";
 	}
 	my $curr = 1;
-	my $destdir = "$poolbase/$poolname";
 	foreach my $chan (@selected_chans) {
-		my $span = $chan->span;
-		my $devfile = sprintf "/dev/dahdi/spans/%03d/%02d", $span->num, $chan->index;
-		warn "Missing '$devfile'\n" unless -c $devfile;
-		my $dest = "$destdir/$curr";
-		$self->save_linkinfo($devfile, $dest);
+		$self->save_linkinfo($chan, $curr);
 		$curr++;
 	}
 	return $self;
 }
 
+sub pools_populate() {
+	foreach my $poolname (keys %pool_components) {
+		my $p = Dahdi::Pool->new($poolname, $pool_components{$poolname});
+		$pools{$poolname} = $p if defined $p;
+	}
+}
+
 sub dev2poolentry($) {
 	my $class = shift || die;
 	my $devt = shift || die;
-	my $dev = $devices{$devt};
+	#pools_populate unless %pools;
+	my $dev = $device_nodes{$devt};
 	return $dev;
+}
+
+sub chan2poolentry($) {
+	my $class = shift || die;
+	my $chan = shift || die;
+	pools_populate unless %pools;
+	my $span = $chan->span;
+	my $spanno = $span->num;
+	my $channo = $chan->index;
+	my $poolentry = $poolentry_byspanno[$spanno][$channo];
+	return $poolentry;
 }
 
 sub get_pools() {
 	my $class = shift || die;
-	if(! %pools) {
-		foreach my $poolname (keys %pool_components) {
-			my $p = Dahdi::Pool->new($poolname, $pool_components{$poolname});
-			$pools{$poolname} = $p if defined $p;
-		}
-	}
+	pools_populate unless %pools;
 	return values %pools;
 }
 

Modified: tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Span.pm
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Span.pm?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Span.pm (original)
+++ tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Span.pm Mon May 17 17:27:16 2010
@@ -10,6 +10,7 @@
 use strict;
 use Dahdi;
 use Dahdi::Utils;
+use Dahdi::Pool;
 use Dahdi::Chans;
 use Dahdi::Xpp::Xpd;
 
@@ -142,6 +143,95 @@
 	my @spans = Dahdi::spans();
 	my @matched = grep { defined($_->hardware_id) && $_->hardware_id =~ m/^$span_hardware_id$/ } @spans;
 	return @matched;
+}
+
+sub chans_subset($) {
+	my $span = shift || die;
+	my $channo_str = shift;
+	my @chans = $span->chans;
+	return @chans unless defined $channo_str;	# special case (empty selection)
+	my %channos;
+	foreach my $range (split(/\s*,\s*/, $channo_str)) {
+		my ($start, $end) = split(/\s*-\s*/, $range);
+		die "$0: Empty range in '$channo_str'"
+			unless defined $start;
+		die "$0: Bad start string '$start' in '$channo_str'"
+			unless $start =~ /^\d+$/;
+		if(! defined $end) {
+			$end = $start;
+		}
+		die "$0: Bad end string '$end' in '$channo_str'"
+			unless $end =~ /^\d+$/;
+		die "$0: Downward range '$start-$end' in '$channo_str'"
+			if $start > $end;
+		die "$0: end '$end' larger than maximum " . scalar(@chans) . ""
+			if $end > scalar(@chans);
+		foreach ($start .. $end) {
+			die "$0: Duplicate number '$_' in '$channo_str'" if defined $channos{$_};
+			$channos{$_} = 1;
+		}
+	}
+	my @selected = grep { defined $channos{$_->index} } @chans;
+	return @selected;
+}
+
+# Generate channel range strings from chan objects
+# E.g: "63-77,79-93"
+sub chan_range(@) {
+	my @chans = sort { $a->num <=> $b->num } @_;
+	my @channos = map { $_->num } @chans;
+	return Dahdi::Utils::channo_range(@channos);
+}
+
+# Generate channel range strings from digital span objects
+# E.g: "63-77,79-93"
+# This also support pool prefixes:
+# E.g: "Lab1!63-77,79-93"
+sub map_channel_range(@) {
+	my $span = shift || die;
+	my @poolchans = @_;
+	my @chans;
+	my $poolname;
+	my $chans_str;
+	foreach my $chan (@poolchans) {
+		my $poolidx;
+		my $pe = Dahdi::Pool->chan2poolentry($chan);
+		if(defined $pe) {
+			my $pool = $pe->{POOL};
+			if(! defined $poolname) {
+				die "$0: No poolname for " . $chan->fqn . "" unless $pool->{NAME};
+				$poolname = $pool->{NAME};
+				$chans_str = sprintf "%s!", $pool->{POOLSTR};
+			} elsif($poolname ne $pool->{NAME}) {
+				die "$0: Mixed pools in a span: was '$poolname', now '$pool->{NAME}'"
+			}
+			$poolidx = $pe->{POOLIDX};
+			push(@chans, $poolidx);
+		} elsif (defined $poolname) {
+			die "$0: Non-pool channel (" . $chan->fqn . ") while inside '$poolname'";
+		} else {
+			push(@chans, $chan->num);
+		}
+	}
+	$chans_str .= join(',', @chans);
+	#printf STDERR "map_channel_range(%s)>>>\t $chans_str\n", $span->name;
+	return $chans_str;
+}
+
+sub bchan_range() {
+	my $span = shift || die;
+	die unless $span->is_digital();
+	my @chans = $span->bchans();
+	my $str = $span->map_channel_range(@chans);
+	return $str;
+}
+
+sub dchan_string() {
+	my $span = shift || die;
+	die unless $span->is_digital();
+	my @chans = $span->dchan();
+	my $str = $span->map_channel_range(@chans);
+	return $str;
 }
 
 my @bri_strings = (
@@ -206,8 +296,8 @@
 	my $span = shift || die;
 	my $location;
 	$location = $span->_get_dev_attr('location');
+	$location =~ tr/a-zA-Z0-9.!:-/_/c;	# Cleanup
 	$location =~ s/^/@/;			# Add prefix
-	$location =~ tr/[a-zA-Z0-9.!:-]/_/c;	# Cleanup
 	$span->{LOCATION} = $location;
 }
 
@@ -244,7 +334,7 @@
 	# FIXME: the following is a number, rather than a readable value:
 	$self->{ALARMS} = $self->_get_dev_attr('alarms');
 	$self->{HARDWARE_ID} = $self->_get_dev_attr('hardware_id');
-	$self->{HARDWARE_PORT} = $self->_get_dev_attr('hardware_port');
+	$self->{SPAN_ID} = $self->_get_dev_attr('span_id');
 	if ($self->spantype =~ /^(TE|NT|BRI|BRI_(NT|TE))$/) {
 		# FIXME: BRI modules of wct24xxp?
 		$self->{IS_DIGITAL} = 1;
@@ -406,8 +496,12 @@
 
 sub bchans($) {
 	my $self = shift || die;
-
 	return @{$self->{BCHANS}};
+}
+
+sub dchan($) {
+	my $self = shift || die;
+	return $self->{DCHAN};
 }
 
 sub set_termtype($$) {

Modified: tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Utils.pm
URL: http://svnview.digium.com/svn/dahdi/tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Utils.pm?view=diff&rev=8654&r1=8653&r2=8654
==============================================================================
--- tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Utils.pm (original)
+++ tools/team/tzafrir/sysfs/xpp/perl_modules/Dahdi/Utils.pm Mon May 17 17:27:16 2010
@@ -48,6 +48,44 @@
 	}
 }
 
+sub range_string($$) {
+	my ($start, $end) = @_;
+
+	if($start == $end) {
+		sprintf "%d", $start;
+	} else {
+		sprintf "%d-%d", $start, $end;
+	}
+}
+
+# Generate channel range strings from arrays of chan numbers
+# E.g: "63-77,79-93"
+sub channo_range(@) {
+	my @channos = sort { $a <=> $b } @_;
+	my $first_num = $channos[0];
+	my $range_start = $first_num;
+	my @range;
+	my $prev = undef;
+
+	foreach my $c (@channos) {
+		my $curr = $c;
+		if(!defined($prev)) {
+			# First iteration
+			$prev = $curr;
+		} elsif($curr != $prev + 1) {
+			# New range
+			push(@range, range_string($range_start, $prev));
+			$range_start = $curr;
+		}
+		$prev = $curr;
+	}
+	if($prev >= $first_num) {
+		# Last range
+		push(@range, range_string($range_start, $prev));
+	}
+	return join(',', @range);
+}
+
 sub glob2regex($) {
 	my $glob = shift || die;
 	$glob =~ s/\*/.*/g;




More information about the dahdi-commits mailing list