[Pkg-voip-commits] r6673 - in /druid/trunk: admin/ debian/ debian/patches/

tzafrir-guest at alioth.debian.org tzafrir-guest at alioth.debian.org
Thu Jan 15 18:11:06 UTC 2009


Author: tzafrir-guest
Date: Thu Jan 15 18:11:05 2009
New Revision: 6673

URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=6673
Log:
[svn-inject] Applying Debian modifications to trunk

Added:
    druid/trunk/debian/   (with props)
    druid/trunk/debian/README.Debian
    druid/trunk/debian/TODO.Debian
    druid/trunk/debian/changelog
    druid/trunk/debian/compat
    druid/trunk/debian/control
    druid/trunk/debian/copyright
    druid/trunk/debian/dirs
    druid/trunk/debian/docs
    druid/trunk/debian/druid_apache2.conf
    druid/trunk/debian/info
    druid/trunk/debian/install
    druid/trunk/debian/patches/
    druid/trunk/debian/patches/dbconfig
    druid/trunk/debian/patches/debian_pathes
    druid/trunk/debian/patches/disable_upgrade_check
    druid/trunk/debian/patches/edit_zapscan
    druid/trunk/debian/patches/script_include_path
    druid/trunk/debian/patches/series
    druid/trunk/debian/patches/zaptel_hardware
    druid/trunk/debian/patches/zaptelconf_readonly
    druid/trunk/debian/rules   (with props)
    druid/trunk/debian/watch.ex
    druid/trunk/debian/zapconf-druid
Modified:
    druid/trunk/admin/SystemUtils.html.php

Modified: druid/trunk/admin/SystemUtils.html.php
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/admin/SystemUtils.html.php?rev=6673&op=diff
==============================================================================
--- druid/trunk/admin/SystemUtils.html.php (original)
+++ druid/trunk/admin/SystemUtils.html.php Thu Jan 15 18:11:05 2009
@@ -287,7 +287,7 @@
          });
       }
       else {
-         var def = jsoncall('SystemUtils', 'enableService', name);
+         var def = jsoncall('SystemUtils', 'enableSERVICE', name);
          def.addCallback(function (msg) {
             infoDialog(msg);
             update_service_status(name);

Propchange: druid/trunk/debian/
------------------------------------------------------------------------------
    mergeWithUpstream = 1

Added: druid/trunk/debian/README.Debian
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/README.Debian?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/README.Debian (added)
+++ druid/trunk/debian/README.Debian Thu Jan 15 18:11:05 2009
@@ -1,0 +1,37 @@
+druid-ose for Debian
+--------------------
+
+I currently assume the httpd is apache2, though I know of no inherent
+requirement for it. Let me know if you managed to get it working with
+e.g. lighttd (and how).
+
+mod_proxy needs to be enabled:
+
+  a2enmod proxy
+  a2enmod rewrite
+  /etc/init.d/apache2 restart
+
+Initial login
+-------------
+Initial username *must* be 'admin' (TODO: why?)
+Note that Druid currently reads manager.conf directly and its parser
+does not support '#include'.
+(TODO: what are the exact required permissions? can it be in an included 
+file?) and login using that username and password.
+
+It seems that the web server needs read and write access to the Asterisk
+configuration files. Without read access almost nothing will work.
+
+Specifically:
+* sip.conf
+* iax.conf
+* zapata.conf
+* voicemail.conf
+* extensions.conf
+* queus.conf
+* rtp.conf
+
+
+Probably: adduser www-data asterisk # adds www-data to group asterisk
+
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Sat, 20 Dec 2008 23:04:35 +0200

Added: druid/trunk/debian/TODO.Debian
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/TODO.Debian?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/TODO.Debian (added)
+++ druid/trunk/debian/TODO.Debian Thu Jan 15 18:11:05 2009
@@ -1,0 +1,9 @@
+* Write a proper backup script, rather than 'sudo cp' and alike today.
+* Configire its run through sudo
+* Insecure temporary file names in Backup.php, insall.pl
+* core/LeaseWatcher.php:   $fh = fopen("/var/lib/dhcpd/dhcpd.leases",'rb')
+* web interface uses asterisk -rnx needlessly. Use manager instead.
+* Use libjs-jquery rather than embedded jquery.js (what about .form?)
+* Use a compiled dojo, saving most of the runtime space.
+* Package dojo (RFP: #497122) and use it.
+

Added: druid/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/changelog?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/changelog (added)
+++ druid/trunk/debian/changelog Thu Jan 15 18:11:05 2009
@@ -1,0 +1,7 @@
+druid (1.3.9.svn.291-1) unstable; urgency=low
+
+  * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
+  * FIXME: RFP of dojo: 497122.
+
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Sat, 20 Dec 2008 23:04:35 +0200
+

Added: druid/trunk/debian/compat
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/compat?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/compat (added)
+++ druid/trunk/debian/compat Thu Jan 15 18:11:05 2009
@@ -1,0 +1,1 @@
+7

Added: druid/trunk/debian/control
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/control?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/control (added)
+++ druid/trunk/debian/control Thu Jan 15 18:11:05 2009
@@ -1,0 +1,18 @@
+Source: druid
+Section: comm
+Priority: extra
+Maintainer: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+# requires "java >= 1.4.2" for compiling dojo. Though I don't actually use it.
+Build-Depends: debhelper (>= 7), quilt, java5-runtime
+Standards-Version: 3.8.0
+Homepage: http://voiceroute.org
+
+Package: druid
+Architecture: all
+Depends: ${misc:Depends}, asterisk, zaptel, 
+ php5-cli, libapache2-mod-php5 | libapache2-mod-php5 | php5-cgi,
+ php5-pgsql, druid-pgsql
+Recommends: postgresql-8.3 | postgresql
+Description: PBX based on Asterisk
+ A complete PBX based on Asterisk. Provides a web-based 
+ configuration interface [COMPLETE DESCRIPTION]

Added: druid/trunk/debian/copyright
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/copyright?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/copyright (added)
+++ druid/trunk/debian/copyright Thu Jan 15 18:11:05 2009
@@ -1,0 +1,42 @@
+This package was debianized by Tzafrir Cohen <tzafrir.cohen at xorcom.com> on
+Sat, 20 Dec 2008 23:04:35 +0200.
+
+It was downloaded from <url://example.com>
+
+# Upstream claim that licese is GPL2. Not throughly checked yet.
+# Includes dojo, which is probably BSD.
+Upstream Author(s):
+
+    <put author's name and email here>
+    <likewise for another author>
+
+Copyright:
+
+    <Copyright (C) YYYY Name OfAuthor>
+    <likewise for another author>
+
+License:
+
+    This package is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This package is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this package; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
+The Debian packaging is (C) 2008, Tzafrir Cohen <tzafrir.cohen at xorcom.com> and
+is licensed under the GPL, see above.
+
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.

Added: druid/trunk/debian/dirs
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/dirs?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/dirs (added)
+++ druid/trunk/debian/dirs Thu Jan 15 18:11:05 2009
@@ -1,0 +1,2 @@
+etc/apache2/conf.d
+usr/share/druid

Added: druid/trunk/debian/docs
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/docs?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/docs (added)
+++ druid/trunk/debian/docs Thu Jan 15 18:11:05 2009
@@ -1,0 +1,2 @@
+apidocs
+CREDITS

Added: druid/trunk/debian/druid_apache2.conf
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/druid_apache2.conf?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/druid_apache2.conf (added)
+++ druid/trunk/debian/druid_apache2.conf Thu Jan 15 18:11:05 2009
@@ -1,0 +1,50 @@
+Alias /druid /usr/share/druid/www
+
+<Directory "/usr/share/druid/www">
+  # Don't show directory listings for URLs which map to a directory.
+  Options -Indexes
+  
+  # Follow symbolic links in this directory.
+  Options +FollowSymLinks
+  
+  # Customized error messages.
+  # ErrorDocument 404 /druid/index.php
+  
+  # Set the default handler.
+  DirectoryIndex index.php
+  
+  # Override PHP settings. More in sites/default/settings.php
+  # but the following cannot be changed at runtime.
+  php_value memory_limit 30M
+  
+  # PHP 5, Apache 1 and 2.
+  <IfModule mod_php5.c>
+    php_value magic_quotes_gpc                0
+    php_value register_globals                0
+    php_value session.auto_start              0
+    php_value mbstring.http_input             pass
+    php_value mbstring.http_output            pass
+    php_value mbstring.encoding_translation   0
+    php_value upload_max_filesize             20M
+    php_value post_max_size                   20M
+  </IfModule>
+  
+  # Requires mod_expires to be enabled.
+  <IfModule mod_expires.c>
+    # Enable expirations.
+    ExpiresActive On
+    # Cache all files for 2 weeks after access (A).
+    ExpiresDefault A1209600
+    # Do not cache dynamically generated pages.
+    ExpiresByType text/html A1
+  </IfModule>
+  
+  # Various rewrite rules.
+  <IfModule mod_rewrite.c>
+    RewriteEngine on
+  
+    RewriteRule ^[pP]hone/(.*)$ phones/provision.php?name=Any&query=$1
+  </IfModule>
+</Directory>
+
+ProxyPass /ajam http://localhost:8088/asterisk

Added: druid/trunk/debian/info
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/info?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/info (added)
+++ druid/trunk/debian/info Thu Jan 15 18:11:05 2009
@@ -1,0 +1,1 @@
+js/dojoroot/util/jsdoc/jsdoc.info

Added: druid/trunk/debian/install
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/install?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/install (added)
+++ druid/trunk/debian/install Thu Jan 15 18:11:05 2009
@@ -1,0 +1,10 @@
+debian/druid_apache2.conf		etc/apache2/conf.d
+admin changepin.php core css		usr/share/druid/www
+druid.wsdl.php images index.html 	usr/share/druid/www
+index.php js leasewatcher.php lib 	usr/share/druid/www
+locale login.php phones regular 	usr/share/druid/www
+services services.php soap.php	 	usr/share/druid/www
+upgrade.php wsdl-viewer.xsl 		usr/share/druid/www
+lib					usr/share/druid
+tools					usr/share/druid
+debian/zapconf-druid			usr/share/druid/tools

Added: druid/trunk/debian/patches/dbconfig
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/dbconfig?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/dbconfig (added)
+++ druid/trunk/debian/patches/dbconfig Thu Jan 15 18:11:05 2009
@@ -1,0 +1,37 @@
+--- a/core/db/PGSql.php
++++ b/core/db/PGSql.php
+@@ -4,22 +4,27 @@
+    class PGSql {
+       private $primary_key_field;
+       private $table;
++      private $conn_str;
+       private $connection_hndl;
+ 
+       function __construct($table, $primary_key_field) {
+          $this->table = $table;
+          $this->primary_key_field = $primary_key_field;
+ 
+-         $astdb = new ConfigFile('/etc/asterisk/res_pgsql.conf');
+-         $allfields = $astdb->getVariableTable('general');
+-         if (!function_exists('pg_connect')) {
+-            //die("PHP PGSQL functionality not loaded");
+-            return;
+-         }
++	 # Not requite_once . Seems to be used twice???
++	 # (Tzafrir)
++	 require '/etc/druid/debian-db.php';
+          
+-         $this->connection_hndl = pg_connect("host={$allfields['dbhost']} port={$allfields['dbport']} dbname={$allfields['dbname']} user={$allfields['dbuser']} password={$allfields['dbpass']}");
++	 $conn_str = '';
++	 if ($dbserver != '') { $conn_str = $conn_str."host=$dbserver "; }
++	 if ($dbport != ''  ) { $conn_str = $conn_str."port=$dbport "; }
++	 if ($dbname != ''  ) { $conn_str = $conn_str."dbname=$dbname "; }
++	 if ($dbuser != ''  ) { $conn_str = $conn_str."user=$dbuser "; }
++	 if ($dbpass != ''  ) { $conn_str = $conn_str."password=$dbpass "; }
++         $this->connection_hndl = pg_connect( $conn_str);
+       }
+ 
++
+       function fetch($id) {
+          if (is_array($id)) {
+             $clause = array();

Added: druid/trunk/debian/patches/debian_pathes
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/debian_pathes?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/debian_pathes (added)
+++ druid/trunk/debian/patches/debian_pathes Thu Jan 15 18:11:05 2009
@@ -1,0 +1,11 @@
+--- a/admin/Sounds.php
++++ b/admin/Sounds.php
+@@ -18,7 +18,7 @@ class Sounds extends Page {
+       'sln' => 'slin',
+       'gsm' => 'gsm'
+    );
+-	private $astsounddir = '/var/lib/asterisk/sounds/';
++	private $astsounddir = '/usr/share/asterisk/sounds/';
+ 
+    function __construct() {
+       parent::__construct();

Added: druid/trunk/debian/patches/disable_upgrade_check
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/disable_upgrade_check?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/disable_upgrade_check (added)
+++ druid/trunk/debian/patches/disable_upgrade_check Thu Jan 15 18:11:05 2009
@@ -1,0 +1,14 @@
+--- a/core/Login.php
++++ b/core/Login.php
+@@ -38,11 +38,6 @@ class Login extends Page {
+       textdomain("messages");
+ 
+ 
+-      if ($this->checkUpgrade()) {
+-         header('Location: upgrade.php');
+-         die(_("Supposed to upgrade"));
+-      }
+-
+ 		$GLOBALS['self'] = $_SERVER['REQUEST_URI'];
+ 		ini_set('session.gc_maxlifetime','6000');
+ 	

Added: druid/trunk/debian/patches/edit_zapscan
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/edit_zapscan?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/edit_zapscan (added)
+++ druid/trunk/debian/patches/edit_zapscan Thu Jan 15 18:11:05 2009
@@ -1,0 +1,995 @@
+--- a/admin/HardwareWizard.php
++++ b/admin/HardwareWizard.php
+@@ -54,7 +54,8 @@
+       function detectTelephonyHardware() {
+          $channels = $this->detectHardware();
+ 
+-         $zc = new ZaptelConfig('/etc/zaptel.conf');
++	 touch('/var/spool/asterisk/tmp/zaptel.conf');
++         $zc = new ZaptelConfig('/var/spool/asterisk/tmp/zaptel.conf');
+          $zapata = new ZapConfig('/etc/asterisk/zapata.conf');
+ 
+          $ret = array();
+@@ -63,8 +64,8 @@
+             $node = new HardwareDetectNode();
+             $node->ChannelType = $obj['type'] . " Port";
+             $node->Model = $obj['description'];
+-            if (($chn = $this->checkIfSpanExists($spannum,$zc)) !== FALSE) {
+-               $ctype = $zc->detectZaptelNodeType($chn[1]);
++            if (($zc_span = $this->checkIfSpanExists($spannum,$zc)) !== FALSE) {
++               $ctype = $zc_span->Type();
+                $ctypeclass = $zc->getPortTypeClass($ctype);
+                $node->Ports = $zc->getPorts($ctypeclass,$chn[1]);
+                $node->Channels = $zc->getChannels($ctype, $chn[1]);
+@@ -99,8 +100,14 @@
+       
+       function checkIfSpanExists($span, $zc = FALSE) {
+          if ($zc === FALSE) {
+-            $zc = new ZaptelConfig('/etc/zaptel.conf');
++            $zc = new ZaptelConfig('');
+          }
++	 $zc_span = $zc->SpanByNum($span);
++	 if ($zc_span == NULL) {
++		 return FALSE;
++	 }
++	 return $span;
++
+          foreach ($zc->channels as $i => $obj) {
+             $num = explode(",",$obj->value);
+             $num = $num[0];
+@@ -113,129 +120,34 @@
+ 
+ 
+       function detectHardware() {
+-         $channels = array();
+-         if (!file_exists('/proc/zaptel')) {
+-         }
+-         else {
+-            $sdir = scandir("/proc/zaptel");
+-            foreach ($sdir as $span) {
+-               if (($span == '.') || ($span == '..'))
+-                  continue;
+-               if (!isset($channels[$span]))
+-                  $channels[$span] = array();
+-               $lines = file("/proc/zaptel/$span");
+-               foreach ($lines as $line) {
+-                  if (trim($line) == "")
+-                     continue;
+-                  if (strpos($line, "Span") !== FALSE)
+-                     continue;
+-                  list($chan_num, $rest) = explode(" ",trim($line),2);
+-                  foreach ($this->channeldetect as $type => $patterns) {
+-                     $channels[$span]['ntype'] = $type;
+-                     foreach ($patterns as $pattern => $desc) {
+-                        if (preg_match("/$pattern/", $line)) {
+-                           $channels[$span]['ndescription'] = $desc;
+-                           switch ($type) {
+-                              case 'wctdm':
+-                                 // Either FXO or FXS -- must detect
+-                                 $is_fxo = $is_fxs = 0;
+-                                 file_put_contents('/tmp/fxo',"fxsks=$chan_num");
+-                                 file_put_contents('/tmp/fxs',"fxoks=$chan_num");
+-                                 $is_fxo = `/usr/bin/sudo /sbin/ztcfg -c /tmp/fxo \&>/dev/null && echo -n 1 || echo -n 0`;
+-                                 $is_fxs = `/usr/bin/sudo /sbin/ztcfg -c /tmp/fxs \&>/dev/null && echo -n 1 || echo -n 0`;
+-                                 $is_fxo = (int)$is_fxo;
+-                                 $is_fxs = (int)$is_fxs;
+-                                 unlink("/tmp/fxo");
+-                                 unlink("/tmp/fxs");
+-                                 if (($is_fxo && $is_fxs) || (!$is_fxo && !$is_fxs)) {
+-                                    // Configure as neither
+-                                    $channels[$span]['channels'][$chan_num] = array('val'=>'unknown');
+-                                 }
+-                                 elseif ($is_fxo) {
+-                                    $channels[$span]['channels'][$chan_num] = array('val'=>'fxo','desc'=>$desc);
+-                                 }
+-                                 elseif ($is_fxs) {
+-                                    $channels[$span]['channels'][$chan_num] = array('val'=>'fxs','desc'=>$desc);
+-                                 }
+-                                 break;
+-                              case 'wcfxo':
+-                              case 'wcusb':
+-                              case 'xpp_fxo':
+-                              case 'fxo':
+-                                 $channels[$span]['channels'][$chan_num] = array('val'=>'fxo','desc'=>$desc);
+-                                 break;
+-
+-                              case 'xpp_fxs':
+-                              case 'xpp_in':
+-                              case 'xpp_out':
+-                              case 'fxs':
+-                                 $channels[$span]['channels'][$chan_num] = array('val'=>'fxs','desc'=>$desc);
+-                                 break;
+-
+-                              case 't1e1pri':
+-                                 $channels[$span]['channels'][$chan_num] = 'pri';
+-                                 break;
+-                              default:
+-                                 $channels[$span]['channels'][$chan_num] = array('val'=>'unknown');
+-                           }
+-                           break;
+-                        } 
+-                     }
+-                     if (isset($channels[$span]['channels'][$chan_num])) {
+-                        break;
+-                     }
+-                  }
+-               }
+-               //ksort($channels[$span]['channels'],SORT_NUMERIC);
+-               $keys = array_keys($channels[$span]['channels']);
+-               sort($keys, SORT_NUMERIC);
+-               switch ($channels[$span]['ntype']) {
+-                  case 't1e1pri': 
+-                     if (count($keys) == 24) {
+-                        $channels[$span]['type'] = 'T1';
+-                        $channels[$span]['framing'] = 'esf';
+-                        $channels[$span]['coding'] = 'b8zs';
+-                     }
+-                     else {
+-                        $channels[$span]['type'] = 'E1';
+-                        $channels[$span]['framing'] = 'hdb3';
+-                        $channels[$span]['coding'] = 'ccs';
+-                     }
+-                     $channels[$span]['num'] = $span;
+-                     $channels[$span]['begin'] = $keys[0];
+-                     $channels[$span]['end'] = $keys[count($keys)-1];
+-                     $channels[$span]['switchtype'] = 'national';
+-                     $channels[$span]['signalling'] = 'pri_cpe';
+-                     $channels[$span]['description'] = $channels[$span]['ndescription'];
+-                     break;
+-                  default:
+-                     foreach ($channels[$span]['channels'] as $num => $obj) {
+-                        if ($obj['val'] != 'unknown') {
+-                           $n = (string)$num;
+-                           $channels[$n]['type'] = strtoupper($obj['val']);
+-                           $channels[$n]['description'] = $obj['desc'];
+-                           $channels[$n]['begin'] = $num;
+-                           $channels[$n]['end'] = $num;
+-                           $channels[$n]['signalling'] = ($obj['val'] == 'fxo') ? 'fxs_ks' : 'fxo_ks';
+-                        }
+-                     }
+-               }
+-               unset($channels[$span]['channels']);
+-               unset($channels[$span]['ntype']);
+-               unset($channels[$span]['ndescription']);
+-               if (!isset($channels[$span]['type'])) {
+-                  unset($channels[$span]);
+-               }
+-            }
+-         }
+-         
+-         return $channels;
+-      }
+-
+-      function unconfigureZapChannel($span) {
+-         $this->unsetChannels(array($span));
+-
+-         return sprintf(_("Successfully removed configuration for port %s"),$span);
++	      $channels = array();
++	      system('/usr/share/druid/tools/zapconf-druid asterisk', $retval);
++	      if ($retval) {
++		      // TODO: notice error
++		      return $channels;
++	      }
++
++	      # Parse the detected configuration:
++	      $zapconf = new ConfigFile('/var/lib/asterisk/druid-detected-zap.conf');
++	      $span_names = array();
++	      foreach (preg_grep('/^span/', array_keys($zapconf->headers)) as $sect) {
++		      $span = $zapconf->ht_variables[$sect];
++		      $span_num = $span['num'];
++		      $channels[$span_num] = array();
++		      $channels[$span_num]['ntype'] = $span['type'];
++		      $channels[$span_num]['ndescription'] = $span['description'];
++		      $span_names[$span['name']] = $span_num;
++		      # FIXME: handle digital spans
++	      }
++	      foreach (preg_grep('/^chan/', array_keys($zapconf->headers)) as $sect) {
++		      $chan = $zapconf->ht_variables[$sect];
++		      $span_num = $span_names[$chan['span']];
++		      $chan_type = $chan['type'];
++		      $chan_type = preg_replace('/_[a-z]*$/', '', $chan_type);
++		      $channels[$span_num]['val'] = $chan_type;
++		      $channels[$span_num]['desc'] = $chan['name'];
++	      }
++	      return $channels;
+       }
+ 
+       function unsetChannels($spans) {
+@@ -246,11 +158,11 @@
+          $delpatterns = array();
+          $delctx = array();
+          foreach ($spans as $i => $span) {
+-            $zaptel_chan = $this->checkIfSpanExists($span,$zaptel);
+-            if ($zaptel_chan === FALSE) {
++            $zc_span = $this->checkIfSpanExists($span,$zaptel);
++            if ($zc_span === FALSE) {
+                continue;
+             }
+-            $ctype = $zaptel->detectZaptelNodeType($zaptel_chan[1]);
++	    $ctype = $zc_span->SpanType();
+             $ctypeclass = $zaptel->getPortTypeClass($ctype);
+             $ports = $zaptel->getPorts($ctypeclass,$zaptel_chan[1]);
+             unset($zaptel->channels[$zaptel_chan[0]]);
+@@ -315,7 +227,6 @@
+          $channels = $this->detectHardware();
+          $spans = array_keys($channels);
+          $this->unsetChannels($spans);
+-         $zaptel = new ZaptelConfig('/etc/zaptel.conf');
+          $zapata = new ZapConfig('/etc/asterisk/zapata.conf');
+ 
+          $group = -1;
+@@ -334,10 +245,8 @@
+             $callerid = "asreceived";
+ 
+             $pos_zapata = count($zapata->channels);
+-            $pos_zaptel = count($zaptel->channels);
+ 
+             $zapata->channels[$pos_zapata] = new ZapChannel();
+-            $zaptel->channels[$pos_zaptel] = new ZaptelNode();
+ 
+             $zapata->channels[$pos_zapata]->vars['callerid'] = $callerid;
+ 
+@@ -347,8 +256,6 @@
+                   $group++;
+                }
+                $end_channel = $start_channel;
+-               $zaptel->channels[$pos_zaptel]->name = 'fxsks';
+-               $zaptel->channels[$pos_zaptel]->value = $start_channel;
+ 
+                $zapata->channels[$pos_zapata]->name = 'channel';	
+                $zapata->channels[$pos_zapata]->value = $start_channel;
+@@ -362,8 +269,6 @@
+                   $group++;
+                }
+                $end_channel = $start_channel;
+-               $zaptel->channels[$pos_zaptel]->name = 'fxoks';
+-               $zaptel->channels[$pos_zaptel]->value = $start_channel;
+ 
+                $zapata->channels[$pos_zapata]->name = 'channel';	
+                $zapata->channels[$pos_zapata]->value = $start_channel;
+@@ -385,13 +290,6 @@
+                $bchan = "$start_channel-".($end_channel-1);
+                $dchan = $end_channel;
+ 
+-               $zaptel->channels[$pos_zaptel]->name = 'span';
+-               $zaptel->channels[$pos_zaptel]->value = "$span,$span,0,esf,b8zs";
+-
+-               $zaptel->channels[$pos_zaptel]->vars['bchan'] = $bchan;
+-
+-               $zaptel->channels[$pos_zaptel]->vars['dchan'] = $dchan;
+-
+                $zapata->channels[$pos_zapata]->name = 'channel';	
+                $zapata->channels[$pos_zapata]->value = $bchan;
+ 
+@@ -411,13 +309,6 @@
+                $bchan1 = "$start_channel-".($dchan-1);
+                $bchan2 = ($dchan+1)."-$end_channel";
+ 
+-               $zaptel->channels[$pos_zaptel]->name = 'span';
+-               $zaptel->channels[$pos_zaptel]->value = "$span,$span,0,ccs,hdb3,crc4";
+-
+-               $zaptel->channels[$pos_zaptel]->vars['bchan'] = "$bchan1,$bchan2";
+-
+-               $zaptel->channels[$pos_zaptel]->vars['dchan'] = "$dchan";
+-
+                $zapata->channels[$pos_zapata]->name = 'channel';	
+                $zapata->channels[$pos_zapata]->value = "$bchan1,$bchan2";
+ 
+@@ -436,7 +327,6 @@
+          }
+ 
+          $zapata->commit();
+-         $zaptel->commit();
+          
+          $acmd = new AsteriskCmdStack();
+          $acmd->push("restart_now");
+@@ -449,7 +339,6 @@
+ 
+       function configureZapChannel() {
+          $zapata = new ZapConfig('/etc/asterisk/zapata.conf');
+-         $zaptel = new ZaptelConfig('/etc/zaptel.conf');
+ 
+          $hwtype = $_POST['hwtype'];
+          //$hwcount = $_POST['hwcount'];
+@@ -497,10 +386,8 @@
+          $callerid = "asreceived";
+ 
+          $pos_zapata = count($zapata->channels);
+-         $pos_zaptel = count($zaptel->channels);
+ 
+          $zapata->channels[$pos_zapata] = new ZapChannel();
+-         $zaptel->channels[$pos_zaptel] = new ZaptelNode();
+ 
+          $zapata->channels[$pos_zapata]->vars['callerid'] = $callerid;
+          $zapata->channels[$pos_zapata]->vars['group'] = $group;
+@@ -516,8 +403,6 @@
+          switch($hwtype) {
+          case 'fxo':
+             $end_channel = $start_channel;
+-            $zaptel->channels[$pos_zaptel]->name = 'fxsks';
+-            $zaptel->channels[$pos_zaptel]->value = $start_channel;
+ 
+             $zapata->channels[$pos_zapata]->name = 'channel';	
+             $zapata->channels[$pos_zapata]->value = $start_channel;
+@@ -528,8 +413,6 @@
+             break;
+          case 'fxs':
+             $end_channel = $start_channel;
+-            $zaptel->channels[$pos_zaptel]->name = 'fxoks';
+-            $zaptel->channels[$pos_zaptel]->value = $start_channel;
+ 
+             $zapata->channels[$pos_zapata]->name = 'channel';	
+             $zapata->channels[$pos_zapata]->value = $start_channel;
+@@ -549,13 +432,6 @@
+             $bchan = "$start_channel-".($end_channel-1);
+             $dchan = $end_channel;
+ 
+-            $zaptel->channels[$pos_zaptel]->name = 'span';
+-            $zaptel->channels[$pos_zaptel]->value = "$span,$span,0,esf,b8zs";
+-
+-            $zaptel->channels[$pos_zaptel]->vars['bchan'] = $bchan;
+-
+-            $zaptel->channels[$pos_zaptel]->vars['dchan'] = $dchan;
+-
+             $zapata->channels[$pos_zapata]->name = 'channel';	
+             $zapata->channels[$pos_zapata]->value = $bchan;
+ 
+@@ -572,13 +448,6 @@
+             $bchan1 = "$start_channel-".($dchan-1);
+             $bchan2 = ($dchan+1)."-$end_channel";
+ 
+-            $zaptel->channels[$pos_zaptel]->name = 'span';
+-            $zaptel->channels[$pos_zaptel]->value = "$span,$span,0,ccs,hdb3,crc4";
+-
+-            $zaptel->channels[$pos_zaptel]->vars['bchan'] = "$bchan1,$bchan2";
+-
+-            $zaptel->channels[$pos_zaptel]->vars['dchan'] = "$dchan";
+-
+             $zapata->channels[$pos_zapata]->name = 'channel';	
+             $zapata->channels[$pos_zapata]->value = "$bchan1,$bchan2";
+ 
+@@ -593,11 +462,9 @@
+          
+ 
+          $zapata->commit();
+-         $zaptel->commit();
+ 
+          $acmd = new AsteriskCmdStack();
+          $acmd->push("restart_now");
+-         $acmd->push("ztcfg");
+          $acmd->execute();
+ 
+          return sprintf(_("Successfully configured %s."),$msg_type);
+--- a/admin/AddUser.php
++++ b/admin/AddUser.php
+@@ -5,7 +5,6 @@ require_once 'core/AutoProvision.php';
+ require_once 'core/AsteriskCmdStack.php';
+ require_once 'core/NetworkConfig.php';
+ require_once 'lib/DruidUser.php';
+-require_once "core/ZaptelConfig.php";
+ require_once "core/ZapConfig.php";
+ 
+ 
+--- a/admin/ManageInboundRoutes.php
++++ b/admin/ManageInboundRoutes.php
+@@ -14,7 +14,7 @@ class RouteNode {
+ class ManageInboundRoutes extends Page {
+ 
+    private $nums;
+-   private $exten, $zaptel; 
++   private $exten;
+    private $key;
+ 
+    
+@@ -24,9 +24,6 @@ class ManageInboundRoutes extends Page {
+       $this->exten = new ExtensionConfig();
+       $this->zc = new ZapConfig('/etc/asterisk/zapata.conf');
+ 
+-      $this->zaptel = new ZaptelConfig('/etc/zaptel.conf');
+-
+-
+       $ctxlist = array('druid-trunks-inbound');
+       foreach ($this->zc->channels as $k => $chn) {
+          if (isset($chn->vars['context'])) {
+@@ -111,7 +108,7 @@ class ManageInboundRoutes extends Page {
+ 
+    function getInboundContexts() {
+       $zc = new ZapConfig('/etc/asterisk/zapata.conf');
+-      $zap = new ZaptelConfig('/etc/zaptel.conf');
++      $zap = new ZaptelConfig();
+       $misdn = new ConfigFile('/etc/asterisk/misdn.conf');
+ 
+       $res = array();
+@@ -132,16 +129,15 @@ class ManageInboundRoutes extends Page {
+             $res[$ctx] = $name . implode(', ', $portslist[$ctx]);
+          }
+          // For T1/E1
+-         else {
+-            $zap_node = $zap->detectNodeFromZapata($chn);
+-            if ($zap_node !== FALSE) {
+-               $type = $zap->detectType($zap_node);
+-               $typeclass = $zap->getPortTypeClass($type);
+-               $ports = $zap->getPorts($typeclass, $zap_node);
+-               $name = sprintf(_('%s Ports'),strtoupper($type)).': ';
+-               $portslist[$ctx][] = $ports;
+-               $res[$ctx] = $name . implode(', ', $portslist[$ctx]);
+-            }
++	 else {
++		 $ports = $chn->value;
++		 $type = $zap->ChansListType($ports);
++		 if ($type == 'unknown') {
++		 	continue;
++		 }
++		 $name = sprintf(_('%s Ports'),strtoupper($type)).': ';
++		 $portslist[$ctx][] = $ports;
++		 $res[$ctx] = $name . implode(', ', $portslist[$ctx]);
+          }
+       }
+ 
+--- a/core/ZaptelConfig.php
++++ b/core/ZaptelConfig.php
+@@ -1,414 +1,175 @@
+ <?
+ 
+-class ZaptelNode {
+-	 public $name, $value;
+-	 public $vars = array();
++class ZaptelDevice {
++	private $vendor;
++	private $product;
++	private $description;
++	private $hardware_name;
++	private $driver;
++	private $loaded; # FIXME: this is raw information. Needs processing.
++
++	function __construct($info_arr) {
++		$this->vendor 		= $info_arr['vendor'];
++		$this->product		= $info_arr['product'];
++		$this->description	= $info_arr['description'];
++		$this->hardware_name	= $info_arr['hardware_name'];
++		$this->driver		= $info_arr['driver'];
++		$this->loaded		= $info_arr['loaded'];
++	}
+ }
+ 
+-class ZaptelConfig {
+-
+-	private $filename;	
+-	private $readonly;
+-	private $zc;
+-	public $channels;
+-	public $global;
++class ZaptelSpan {
++	private $num;
++	private $channel;
++	private $description;
++	private $is_digital;
++	private $port_type;
++	# TODO: PRI features?
++
++	function __construct($info_arr) {
++		$this->channel = array();
++		$this->num		= $info_arr['num'];
++		$this->description	= $info_arr['description'];
++		$this->is_digital	= ($info_arr['digital'] == 'yes');
++		if ($this->is_digital) {
++			$this->port_type = 'isdn';
++			# TODO: This is probably wrong. channel[] contains
++			# different type depending on the type of the span.
++			$this->channel = preg_split('/\s*,\s*/', $info_arr['channels']);
++		} else {
++			$this->port_type = 'analog';
++		}
++	}
+ 
+-	private $keywords = array("span", "dynamic");
+-	private $devices = array(
+-					"fxsks", "fxoks", "fxsgs", "fxogs", "fxsls", "fxols",
+-					"bchan", "dchan", "fxols", "fxols", "e&m", "nethdlc", 
+-					"clear", "fcshdlc", "dacs", "dacsrbs");
+-	//var $groups = array('isdn' => array('bchan', 'dchan'));
++	function setChan($chan) {
++		$this->channel[$chan->Index()] = $chan;
++	}
+ 	
+-
+-	function __construct($filename, $readonly = false) {
+-		$this->filename = $filename;
+-		$this->readonly = $readonly;
+-		$this->global = array();
+-		$this->channels = array();
+-		$this->zc = false;
+-
+-		$this->parseFile();
++	function getPortType() {
++		return $port_type;
+ 	}
+ 
+-	 function parseFile() {
+-		$header = "";
+-		
+-		if(!file_exists($this->filename)) {
+-         throw new DruidException(sprintf(_("Config File %s does not exist."),basename($this->filename)));
+-		}
+-		if(!is_readable($this->filename)) {
+-         throw new DruidException(sprintf(_("READ access to config file %s required"),basename($this->filename)));
+-		}
+-		if((!is_writable($this->filename)) && (!$this->readonly)) {
+-         throw new DruidException(sprintf(_("WRITE access to config file %s required"),basename($this->filename)));
++	function ChanNums() {
++		if ($this->is_digital){
++			return $this->channel;
++		} else {
++			$channels = array();
++			foreach ($this->channel as $chan) {
++				$channels[] = $chan->getNum();
++			}
++			return $channels;
+ 		}
+-			
+-		$lines = file($this->filename);
+-	
+-		$this->zc = false;
+-		$inside = false;
+-      
+-      $bchan = false;
+-      $dchan = false;
+-
+-		foreach($lines as $n => $line) {
+-			$l = trim($line);		
+-			if(empty($l))
+-				continue;
+-	
+-			if($l{0} == '#')
+-				continue;
++	}
++}
+ 
+-			if(($i = strpos($l, '#')) > 0)
+-				$l = substr($l, 0, $i-1);				
++class ZaptelChan {
++	private $span;
++	private $num;   # Global Zaptel channel numbering
++	private $index; # position inside span.
++	private $name;
++	private $signalling;
++	private $type;
++
++	function __construct($span, $info_arr) {
++		$this->span = $span;
++		$this->num		= $info_arr['num'];
++		$this->index		= $info_arr['index'];
++		$this->name		= $info_arr['name'];
++		$this->type		= $info_arr['type'];
++		$this->signalling	= $info_arr['signalling'];
++	}
+ 
+-			$str = trim($l);
+-			list($k, $v) = explode('=', $str, 2);
+-			if(empty($v))
+-				continue;
+-			
+-			$k = trim($k);
+-			$v = trim($v);
+-
+-         if(in_array($k, $this->keywords)) {
+-            if($inside) {
+-               $this->channels[] = $this->zc;
+-            }
+-            $inside = true;
+-
+-            $this->zc = new ZaptelNode();
+-            $this->zc->name = $k;
+-            $this->zc->value = $v;
+-            $this->zc->vars = array();
+-            continue;
+-         }
+-         
+-         if($inside && $bchan && $dchan) {
+-            if(($k != "bchan") && ($k != "dchan") && ($k != "hardhdlc")) {
+-               $this->channels[] = $this->zc;
+-               $inside = false;
+-            }
+-         }
+-
+-         if($inside) {
+-            if($k == "bchan")
+-               $bchan = true;
+-            if(($k == "dchan") || ($k == "hardhdlc"))
+-               $dchan = true;
+-            $this->zc->vars[$k][] = $v;
+-            continue;
+-         }
+-
+-         if(!in_array($k, $this->devices)) {
+-            $this->global[$k] = $v;
+-            continue;
+-         }
+-
+-         $this->zc = new ZaptelNode();
+-         $this->zc->name = $k;
+-         $this->zc->value = $v;
+-         $this->zc->vars = array();
+-         $this->channels[] = $this->zc;
+-      }
+-
+-      if($inside) {
+-         $this->channels[] = $this->zc;
+-         $inside = false;
+-      }
+-
+-         /*
+-
+-			if(in_array($k, $this->keywords)) {
+-            if($inside) {
+-					$this->channels[] = $this->zc;
+-            }
+-            $inside = true;
+-         
+-            $this->zc = new ZaptelNode();
+-      		$this->zc->name = $k;
+-				$this->zc->value = $v;
+-				continue;
+-         }
+-
+-         if($inside) {
+-				$this->zc->vars[$k][] = $v;	
+-            continue;
+-			}
++	function Index() {
++		return $this->index;
++	}
+ 
+-         if(!in_array($k, $this->devices)) {
+-			   $this->global[$k] = $v;
+-            continue;
+-         }
+-
+-			$this->zc = new ZaptelNode();
+-			$this->zc->name = $k;
+-			$this->zc->value = $v;
+-			$this->channels[] = $this->zc;
+-
+-      }
+-      if($inside) {
+-			$this->channels[] = $this->zc;
+-         $inside = false;
+-		}
++	function getNum() {
++		return $this->num;
++	}
++
++	function getSpan() {
++		return $this->span;
++	}
++}
++
++class ZaptelConfig {
++
++	private $filename;
++	private $readonly;
++	private $zc;
++	private $spans;
++	private $hardware;
++	private $channel_map;
++
++	function __construct($filename = '/var/lib/asterisk/asterisk-detect-hardware-zap.conf', $readonly = true) {
++		$this->filename = $filename;
++		$this->readonly = $readonly;
++		$this->span = array();
++		$this->hardware = array();
++		$this->channel_map = array();
++
++		# Parse the detected configuration:
++		$zapconf = new ConfigFile($filename, $readonly);
++		$dev_num = 0;
++		foreach (preg_grep('/^dev-/', array_keys($zapconf->headers)) as $sect) {
++			$dev = $zapconf->ht_variables[$sect];
++			$this->hardware[] = new ZaptelHardware($dev);
++		}
++
++		$span_names = array();
++		foreach (preg_grep('/^span/', array_keys($zapconf->headers)) as $sect) {
++			$span = $zapconf->ht_variables[$sect];
++			$span_num = $span['num'];
++			$new_span = new ZaptelSpan($span);
++			$this->span[$span_num] = $new_span;
++			$span_names[$span['name']] = $new_span;
++			if ($this->is_digital) {
++				# generate dummy channels:
++				foreach ($span->ChanNums() as $chan_num) {
++					$dummy_chan = array();
++					$index = 1;
++					$dummy_chan['num'] = $chan_num;
++					$dummy_chan['index'] = $index++;
++					$dummy_chan['name'] = $span['name'].'/'.$chan_num;
++					$dummy_chan['type'] = $span['type'];
++					$dummy_chan['signalling'] = 'dummy';
++					$new_chan = new ZaptelChan($span, $dummy_chan);
++					$span->setChan($new_chan);
++					$this->channel_map[$chan_num] = $new_chan;
+ 
+-			if ($inside) {
+-				foreach ($groupset as $t => $s) {
+-					if (in_array($k, $this->groups[$t])) {
+-						if ($groupset[$t] === false) {
+-							$groupset[$t] = true;
+-						}
+-					}
+-					else {
+-						if ($groupset[$t] === true) {
+-							$this->channels[] = $this->zc;
+-							$inside = false;
+-							break;
+-						}
+-					}
+-				}
+-			}
+-			if(($keyword = in_array($k, $this->keywords)) || (!$inside)) {
+-				if($keyword && $inside) {
+-					$this->channels[] = $this->zc;
+-					$inside = false;
+-				}
+-				if($keyword || in_array($k, $this->devices)) {
+-					$this->zc = new ZaptelNode();
+-					$this->zc->name = $k;
+-					$this->zc->value = $v;
+-					if($keyword)
+-						$inside = true;
+-					if(!$keyword)
+-						$this->channels[] = $this->zc;
+-					continue;
+ 				}
+-				$this->global[$k] = $v;
+-			}
+-			if($inside) {
+-				$this->zc->vars[$k][] = $v;	
+-				continue;
+ 			}
++			# FIXME: handle digital spans
++		}
++		foreach (preg_grep('/^chan/', array_keys($zapconf->headers)) as $sect) {
++			$chan = $zapconf->ht_variables[$sect];
++			$span_num = $span_names[$chan['span']];
++			$chan_num = $chan['channels'];
++			$span = $this->spans[$span_num];
++			$chan['type'] = preg_replace('/_[a-z]*$/', '', $chan['type']);
++			$new_chan = new ZaptelChan($span, $chan);
++			$span->setChan($new_chan);
++			$this->channel_map[$chan_num] = $new_chan;
+ 		}
+-		if(($this->zc !== false) && $inside)
+-			$this->channels[] = $this->zc;
+-      */
+ 	}
+ 
+-	 function commit() {
+-		$fh = fopen($this->filename, "w");
+-      if ($fh === FALSE)
+-         throw new DruidException(sprintf(_("Error opening %s"),$this->filename));
+-	
+-		foreach($this->global as $k => $v) {
+-			fwrite($fh, "$k=$v\n");
+-		}
+-		foreach($this->channels as $i => $obj) {
+-			if(!in_array($obj->name, $this->keywords))
+-				fwrite($fh, $obj->name.'='.$obj->value."\n");
++	function ChanByNum($num) {
++		if (array_key_exists($num, $this->channel_map) ) {
++			return $this->channel_map[$num];
+ 		}
+-		foreach($this->channels as $i => $obj) {
+-			if(!in_array($obj->name, $this->keywords))
+-				continue;
+-			fwrite($fh, "\n".$obj->name.'='.$obj->value."\n");
+-			foreach($obj->vars as $k => $v) { 
+-				fwrite($fh, $k.'='.(is_array($v) ? implode(',', $v) : $v)."\n");
++		return NULL;
++	}
++
++	function ChannelsListType($chans_str) {
++		$chan_nums = preg_split('/\s*,\s*/', $chans_str);
++		foreach ($chans_num as $chan_num) {
++			$chan = $this->ChanByNum($chan_num);
++			if ($chan != NULL) {
++				return $chan->Type();
+ 			}
+ 		}
+-		fclose($fh);
++		return 'unknown';
+ 	}
+-	
+-   function detectType($obj) {
+-      if(substr($obj->name, 0, 3) == 'fxs')
+-         return 'fxo';
+-      if(substr($obj->name, 0, 3) == 'fxo')
+-         return 'fxs';
+-
+-      $t = explode(',', $obj->value);
+-      array_walk($t, 'trim');
+-      if(($t[3] == 'ccs') || ($t[3] == 'cas')) {
+-         $n = array('e1');
+-         if(isset($obj->vars['fxsks']) || isset($obj->vars['fxsls']) || isset($obj->vars['fxsgs']))
+-            array_push($n, 'fxo_channelbank_e1');
+-         if(isset($obj->vars['fxoks']) || isset($obj->vars['fxols']) || isset($obj->vars['fxogs']))
+-            array_push($n, 'fxs_channelbank_e1');	
+-         return (count($n) == 3) ? 'fxsfxo_channelbank_e1' : array_pop($n);
+-      }	
+-
+-      elseif(($t[3] == 'esf') || ($t[3] == 'd4')) {
+-         $n = array('t1');
+-         if(isset($obj->vars['fxsks']) || isset($obj->vars['fxsls']) || isset($obj->vars['fxsgs']))
+-            array_push($n, 'fxo_channelbank_t1');
+-         if(isset($obj->vars['fxoks']) || isset($obj->vars['fxols']) || isset($obj->vars['fxogs']))
+-            array_push($n, 'fxs_channelbank_t1');
+-         return (count($n) == 3) ? 'fxsfxo_channelbank_t1' : array_pop($n);
+-      }
+-
+-      elseif(($t[0] == 'eth') || ($t[0] == 'ethmf')) {
+-         $n = array('t1');
+-         if(isset($obj->vars['fxsks']) || isset($obj->vars['fxsls']) || isset($obj->vars['fxsgs']))
+-            array_push($n, 'fxo_channelbank_t1');
+-         if(isset($obj->vars['fxoks']) || isset($obj->vars['fxols']) || isset($obj->vars['fxogs']))
+-            array_push($n, 'fxs_channelbank_t1');
+-         return (count($n) == 3) ? 'fxsfxo_channelbank_t1' : array_pop($n);
+-      }
+-   }
+-
+-   function detectZaptelNodeType($obj) {
+-      if(substr($obj->name, 0, 3) == 'fxs')
+-         return 'fxo';
+-      if(substr($obj->name, 0, 3) == 'fxo')
+-         return 'fxs';
+-
+-      $t = explode(',', $obj->value);
+-      array_walk($t, 'trim');
+-
+-      if(($t[3] == 'ccs') || ($t[3] == 'cas')) {
+-         return 'e1';
+-      }	
+-      elseif(($t[3] == 'esf') || ($t[3] == 'd4')) {
+-         return 't1';
+-      }
+-      elseif(($t[0] == 'eth') || ($t[0] == 'ethmf')) {
+-         return 'tdmoe';
+-      }
+-   }
+-
+-
+-   function getChannels($type, $obj) {
+-      if(($type == 'e1') || ($type == 't1')) {
+-         if(isset($obj->vars['bchan']) && isset($obj->vars['dchan'])) {
+-            return sprintf(_("Bearer Channel: %s - Data Channel: %s"), 
+-               (is_array($obj->vars['bchan']) ? implode(', ', $obj->vars['bchan']) : ''), 
+-               (is_array($obj->vars['dchan']) ? implode(', ', $obj->vars['dchan']) : ''));
+-         }
+-         elseif(isset($obj->vars['e&m'])) {
+-            return sprintf(_("E&M Channel: %s"), 
+-               (is_array($obj->vars['e&m']) ? implode(', ', $obj->vars['e&m']) : '')); 
+-         }
+-         elseif(isset($obj->vars['fxoks'])) {
+-            return sprintf(_("FXS Channel: %s"), 
+-               (is_array($obj->vars['fxoks']) ? implode(', ', $obj->vars['fxoks']) : '')); 
+-         }
+-         elseif(isset($obj->vars['fxsks'])) {
+-            return sprintf(_("FXO Channel: %s"), 
+-               (is_array($obj->vars['fxsks']) ? implode(', ', $obj->vars['fxsks']) : '')); 
+-         }
+-         else {
+-            return _("Unsupported/Not defined");
+-         }
+-      }
+-      elseif(($type == 'fxo') || ($type == 'fxs'))
+-         return sprintf(_("Ports Assigned: %s"), $obj->value);
+-      elseif(($type == 'fxo_channelbank_e1') || ($type == 'fxo_channelbank_t1')) {
+-         $c = array();
+-         foreach($obj->vars as $dev => $arr)
+-            $c[] = implode(', ', $arr);
+-
+-         return sprintf(_("Ports Assigned: %s"), implode(', ', $c));
+-      }
+-      elseif(($type == 'fxs_channelbank_e1') || ($type == 'fxs_channelbank_t1')) {
+-         $c = array();
+-         foreach($obj->vars as $dev => $arr)
+-            $c[] = implode(', ', $arr);
+-
+-         return sprintf(_("Ports Assigned: %s"), implode(', ', $c));
+-      }
+-      elseif($type == 'tdmoe') {
+-         $c = array();
+-         foreach($obj->vars as $dev => $arr)
+-            $c[] = implode(', ', $arr);
+-
+-         return sprintf(_("Ports Assigned: %s"), implode(', ', $c));
+-      }
+-
+-
+-   }
+-
+-   function getPortTypeClass($type) {
+-      if(($type == 'e1') 
+-         || ($type == 't1') 
+-         || ($type == 'fxo_channelbank_e1') 
+-         || ($type == 'fxs_channelbank_e1') 
+-         || ($type == 'fxo_channelbank_t1')
+-         || ($type == 'fxs_channelbank_t1') 
+-         || ($type == 'fxsfxo_channelbank_e1')
+-         || ($type == 'fxsfxo_channelbank_t1'))
+-         return 'isdn';
+-
+-      if(($type == 'fxo') || ($type == 'fxs'))
+-         return 'analog';
+-
+-      if($type == 'tdmoe')
+-         return 'ip';
+-
+-      return 'unknown';
+-   }
+-
+-   function getPorts($typeclass, $obj) {
+-      switch($typeclass) {
+-      case 'isdn':
+-      case 'ip':
+-         $chan_list = array();
+-
+-         if(isset($obj->vars['e&m']))
+-            $chan_list[] = implode(",", $obj->vars['e&m']);
+-         if(isset($obj->vars['bchan']))
+-            $chan_list[] = implode(",", $obj->vars['bchan']);
+-         if(isset($obj->vars['fxsks']))
+-            $chan_list[] = implode(",", $obj->vars['fxsks']);
+-         if(isset($obj->vars['fxoks']))
+-            $chan_list[] = implode(",", $obj->vars['fxoks']);
+-         if(isset($obj->vars['fxsgs']))
+-            $chan_list[] = implode(",", $obj->vars['fxsgs']);
+-         if(isset($obj->vars['fxogs']))
+-            $chan_list[] = implode(",", $obj->vars['fxogs']);
+-         if(isset($obj->vars['fxsls']))
+-            $chan_list[] = implode(",", $obj->vars['fxsls']);
+-         if(isset($obj->vars['fxols']))
+-            $chan_list[] = implode(",", $obj->vars['fxols']);
+-
+-
+-          return implode(',', $chan_list);
+-
+-         //$span = explode(',', $obj->value);
+-         //return sprintf("%s", $span[0]);
+-      case 'analog':
+-         return sprintf("%s", $obj->value);
+-      default:
+-         return '['._('Not Defined').']';
+-      }
+-   }
+-
+-   function detectNodeFromZapata($chn) {
+-      foreach ($this->channels as $obj) {
+-         if ($chn->value == $obj->value)
+-            return $obj;
+-
+-         if ((strpos($obj->name,'dynamic') !== FALSE) 
+-         || (strpos($obj->name,'span') !== FALSE)) {
+-
+-            $chan_list = array();
+-
+-            if(isset($obj->vars['bchan']))
+-               $chan_list[] = array_values($obj->vars['bchan']);
+-            if(isset($obj->vars['fxsks']))
+-               $chan_list[] = array_values($obj->vars['fxsks']);
+-            if(isset($obj->vars['fxoks']))
+-               $chan_list[] = array_values($obj->vars['fxoks']);
+-
+-            $chn_n = explode('-', $chn->value, 2);
+-            foreach($chan_list as $c) {
+-               foreach($c as $cnum) {
+-                  $n = explode('-', $cnum, 2);
+-                  if(($chn_n[0] >= $n[0]) && ($chn_n[1] <= $n[1]))
+-                     return $obj; 
+-               }
+-            }
+-         }
+-      }
+-      return false;
+-   }
+ }
+ 
+ 	

Added: druid/trunk/debian/patches/script_include_path
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/script_include_path?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/script_include_path (added)
+++ druid/trunk/debian/patches/script_include_path Thu Jan 15 18:11:05 2009
@@ -1,0 +1,11 @@
+--- a/tools/hardware_setup
++++ b/tools/hardware_setup
+@@ -8,7 +8,7 @@
+       die("Error: The starting extension number must be numeric\n");
+    }
+ 
+-   chdir("../");
++   set_include_path(get_include_path() . PATH_SEPARATOR . '/usr/share/druid/www');
+ 
+    require_once "core/Page.php";
+    require_once "core/ConfigFile.php";

Added: druid/trunk/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/series?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/series (added)
+++ druid/trunk/debian/patches/series Thu Jan 15 18:11:05 2009
@@ -1,0 +1,6 @@
+dbconfig
+disable_upgrade_check
+debian_pathes
+script_include_path
+zaptelconf_readonly
+zaptel_hardware

Added: druid/trunk/debian/patches/zaptel_hardware
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/zaptel_hardware?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/zaptel_hardware (added)
+++ druid/trunk/debian/patches/zaptel_hardware Thu Jan 15 18:11:05 2009
@@ -1,0 +1,174 @@
+Add a new class, ZaptelHardware, to use hardware listing from
+the 'asterisk' output of zapscan-druid
+--- /dev/null
++++ b/core/ZaptelHardware.php
+@@ -0,0 +1,169 @@
++<?php
++
++class ZaptelDevice {
++	private $vendor;
++	private $product;
++	private $description;
++	private $hardware_name;
++	private $driver;
++	private $loaded; # FIXME: this is raw information. Needs processing.
++
++	function __construct($info_arr) {
++		$this->vendor 		= $info_arr['vendor'];
++		$this->product		= $info_arr['product'];
++		$this->description	= $info_arr['description'];
++		$this->hardware_name	= $info_arr['hardware_name'];
++		$this->driver		= $info_arr['driver'];
++		$this->loaded		= $info_arr['loaded'];
++	}
++}
++
++class ZaptelSpan {
++	private $num;
++	private $channel;
++	private $description;
++	private $is_digital;
++	private $port_type;
++	# TODO: PRI features?
++
++	function __construct($info_arr) {
++		$this->channel = array();
++		$this->num		= $info_arr['num'];
++		$this->description	= $info_arr['description'];
++		$this->is_digital	= ($info_arr['digital'] == 'yes');
++		if ($this->is_digital) {
++			$this->port_type = 'isdn';
++			# TODO: This is probably wrong. channel[] contains
++			# different type depending on the type of the span.
++			$this->channel = preg_split('/\s*,\s*/', $info_arr['channels']);
++		} else {
++			$this->port_type = 'analog';
++		}
++	}
++
++	function setChan($chan) {
++		$this->channel[$chan->Index()] = $chan;
++	}
++
++	function getPortType() {
++		return $port_type;
++	}
++
++	function ChanNums() {
++		if ($this->is_digital){
++			return $this->channel;
++		} else {
++			$channels = array();
++			foreach ($this->channel as $chan) {
++				$channels[] = $chan->getNum();
++			}
++			return $channels;
++		}
++	}
++}
++
++class ZaptelChan {
++	private $span;
++	private $num;   # Global Zaptel channel numbering
++	private $index; # position inside span.
++	private $name;
++	private $signalling;
++	private $type;
++
++	function __construct($span, $info_arr) {
++		$this->span = $span;
++		$this->num		= $info_arr['num'];
++		$this->index		= $info_arr['index'];
++		$this->name		= $info_arr['name'];
++		$this->type		= $info_arr['type'];
++		$this->signalling	= $info_arr['signalling'];
++	}
++
++	function Index() {
++		return $this->index;
++	}
++
++	function getNum() {
++		return $this->num;
++	}
++
++	function getSpan() {
++		return $this->span;
++	}
++}
++
++class ZaptelHardware {
++
++	private $filename;
++	private $readonly;
++	private $zc;
++	private $spans;
++	private $hardware;
++	private $channel_map;
++
++	function __construct($filename = '/var/lib/asterisk/asterisk-detect-hardware-zap.conf', $readonly = true) {
++		$this->filename = $filename;
++		$this->readonly = $readonly;
++		$this->span = array();
++		$this->hardware = array();
++		$this->channel_map = array();
++
++		# Parse the detected configuration:
++		$zapconf = new ConfigFile($filename, $readonly);
++		$dev_num = 0;
++		foreach (preg_grep('/^dev-/', array_keys($zapconf->headers)) as $sect) {
++			$dev = $zapconf->ht_variables[$sect];
++			$this->hardware[] = new ZaptelHardware($dev);
++		}
++
++		$span_names = array();
++		foreach (preg_grep('/^span/', array_keys($zapconf->headers)) as $sect) {
++			$span = $zapconf->ht_variables[$sect];
++			$span_num = $span['num'];
++			$new_span = new ZaptelSpan($span);
++			$this->span[$span_num] = $new_span;
++			$span_names[$span['name']] = $new_span;
++			if ($this->is_digital) {
++				# generate dummy channels:
++				foreach ($span->ChanNums() as $chan_num) {
++					$dummy_chan = array();
++					$index = 1;
++					$dummy_chan['num'] = $chan_num;
++					$dummy_chan['index'] = $index++;
++					$dummy_chan['name'] = $span['name'].'/'.$chan_num;
++					$dummy_chan['type'] = $span['type'];
++					$dummy_chan['signalling'] = 'dummy';
++					$new_chan = new ZaptelChan($span, $dummy_chan);
++					$span->setChan($new_chan);
++					$this->channel_map[$chan_num] = $new_chan;
++			# FIXME: handle digital spans
++		}
++		foreach (preg_grep('/^chan/', array_keys($zapconf->headers)) as $sect) {
++			$chan = $zapconf->ht_variables[$sect];
++			$span_num = $span_names[$chan['span']];
++			$chan_num = $chan['channels'];
++			$span = $this->spans[$span_num];
++			$chan['type'] = preg_replace('/_[a-z]*$/', '', $chan['type']);
++			$new_chan = new ZaptelChan($span, $chan);
++			$span->setChan($new_chan);
++			$this->channel_map[$chan_num] = $new_chan;
++	function ChanByNum($num) {
++		if (array_key_exists($num, $this->channel_map) ) {
++			return $this->channel_map[$num];
++		}
++		return NULL;
++	}
++
++	function ChannelsListType($chans_str) {
++		$chan_nums = preg_split('/\s*,\s*/', $chans_str);
++		foreach ($chans_num as $chan_num) {
++			$chan = $this->ChanByNum($chan_num);
++			if ($chan != NULL) {
++				return $chan->Type();
++			}
++		}
++		return 'unknown';
++	}
++}
++
++?>

Added: druid/trunk/debian/patches/zaptelconf_readonly
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/patches/zaptelconf_readonly?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/patches/zaptelconf_readonly (added)
+++ druid/trunk/debian/patches/zaptelconf_readonly Thu Jan 15 18:11:05 2009
@@ -1,0 +1,23 @@
+Make zaptel.conf read-only, and hence don't panic when it's not writable.
+
+--- a/core/ZaptelConfig.php
++++ b/core/ZaptelConfig.php
+@@ -21,7 +21,7 @@ class ZaptelConfig {
+ 	//var $groups = array('isdn' => array('bchan', 'dchan'));
+ 	
+ 
+-	function __construct($filename, $readonly = false) {
++	function __construct($filename, $readonly = true) {
+ 		$this->filename = $filename;
+ 		$this->readonly = $readonly;
+ 		$this->global = array();
+@@ -196,6 +196,9 @@ class ZaptelConfig {
+ 	}
+ 
+ 	 function commit() {
++		 if ($this->readonly) {
++			 return;
++		 }
+ 		$fh = fopen($this->filename, "w");
+       if ($fh === FALSE)
+          throw new DruidException(sprintf(_("Error opening %s"),$this->filename));

Added: druid/trunk/debian/rules
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/rules?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/rules (added)
+++ druid/trunk/debian/rules Thu Jan 15 18:11:05 2009
@@ -1,0 +1,123 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+PACKAGE:=$(shell sed -nre 's/^Source: (.*)$$/\1/p' debian/control)
+DEBVERSION:=$(shell head -n 1 debian/changelog \
+                    | sed -e 's/^[^(]*(\([^)]*\)).*/\1/')
+UPVERSION:=$(shell echo $(DEBVERSION) | sed -e 's/^.*://' -e 's/-[0-9.]*$$//' -e 's/.dfsg$$//')
+SVN_REV:=$(shell echo $(UPVERSION) | sed -e 's/^.*svn\.//')
+SVN_BRANCH:=trunk
+SVN_URL:=http://svn.voiceroute.org/svn/druid/$(SVN_BRANCH)
+DIR_NAME:=$(PACKAGE)-$(UPVERSION)
+TARBALL:=$(PACKAGE)_$(UPVERSION).orig.tar.gz
+
+-include /usr/share/quilt/quilt.make
+
+configure: configure-stamp
+configure-stamp: patch
+	dh_testdir
+	# Add here commands to configure the package.
+
+	touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp  
+	dh_testdir
+
+	# Add here commands to compile the package.
+	#$(MAKE)
+	#docbook-to-man debian/druid.sgml > druid.1
+	
+	#./build_dojo.sh # some day I figure how to use it safely
+
+	touch $@
+
+clean: unpatch clean-unpatched
+clean-unpatched: 
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+
+	# Add here commands to clean up after the build process.
+	#$(MAKE) clean
+
+	dh_clean 
+
+SHAREDIR=$(CURDIR)/debian/druid/usr/share/druid
+DOJOROOT=$(SHAREDIR)/www/js/dojoroot
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+
+	# Add here commands to install the package into debian/druid.
+	#$(MAKE) DESTDIR=$(CURDIR)/debian/druid install
+	dh_install
+	# Remove some useless parts of dojo:
+	rm -rf $(DOJOROOT)/util/buildscripts
+	rm -rf $(DOJOROOT)/dojox/off
+	rm -rf $(DOJOROOT)/dojo/tests
+	find $(DOJOROOT) -name LICENSE | xargs rm -f
+	find $(SHAREDIR) -type f -perm -u+x | xargs chmod a-x
+	chmod +x $(SHAREDIR)/tools/*
+
+
+
+# Build architecture-independent files here.
+binary-arch: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-indep: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs 
+	dh_installdocs
+	dh_installexamples
+#	dh_install
+#	dh_installdebconf	
+#	dh_installinit
+#	dh_installcron
+#	dh_installman
+	dh_link
+	dh_strip
+	dh_compress
+	dh_fixperms
+#	dh_makeshlibs
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+
+print-version:
+	@echo "Debian version:      $(DEBVERSION)"
+	@echo "Upstream version:    $(UPVERSION)"
+	@echo "Subversion revision: $(SVN_REV)"
+
+TARBALL_DIR=../tarballs/$(PACKAGE)-$(UPVERSION).tmp
+get-orig-source:
+	@dh_testdir
+	@[ -d $(TARBALL_DIR) ]||mkdir -p $(TARBALL_DIR)
+	@rm -rf $(TARBALL_DIR)/$(DIR_NAME)
+
+	@echo "Exporting rev. $(SVN_REV) to $(TARBALL_DIR)/$(DIR_NAME)"
+	@svn export -q -r $(SVN_REV) $(SVN_URL) $(TARBALL_DIR)/$(DIR_NAME)
+	@tar czf ../tarballs/$(TARBALL) -C $(TARBALL_DIR) $(DIR_NAME)
+	@echo "Cleaning up..."
+	@rm -rf $(TARBALL_DIR)
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure patch unpatch

Propchange: druid/trunk/debian/rules
------------------------------------------------------------------------------
    svn:executable = *

Added: druid/trunk/debian/watch.ex
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/watch.ex?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/watch.ex (added)
+++ druid/trunk/debian/watch.ex Thu Jan 15 18:11:05 2009
@@ -1,0 +1,23 @@
+# Example watch control file for uscan
+# Rename this file to "watch" and then you can run the "uscan" command
+# to check for upstream updates and more.
+# See uscan(1) for format
+
+# Compulsory line, this is a version 3 file
+version=3
+
+# Uncomment to examine a Webpage
+# <Webpage URL> <string match>
+#http://www.example.com/downloads.php druid-ose-(.*)\.tar\.gz
+
+# Uncomment to examine a Webserver directory
+#http://www.example.com/pub/druid-ose-(.*)\.tar\.gz
+
+# Uncommment to examine a FTP server
+#ftp://ftp.example.com/pub/druid-ose-(.*)\.tar\.gz debian uupdate
+
+# Uncomment to find new files on sourceforge, for devscripts >= 2.9
+# http://sf.net/druid-ose/druid-ose-(.*)\.tar\.gz
+
+# Uncomment to find new files on GooglePages
+# http://example.googlepages.com/foo.html druid-ose-(.*)\.tar\.gz

Added: druid/trunk/debian/zapconf-druid
URL: http://svn.debian.org/wsvn/pkg-voip/druid/trunk/debian/zapconf-druid?rev=6673&op=file
==============================================================================
--- druid/trunk/debian/zapconf-druid (added)
+++ druid/trunk/debian/zapconf-druid Thu Jan 15 18:11:05 2009
@@ -1,0 +1,693 @@
+#! /usr/bin/perl -w
+#
+# Written by Oron Peled <oron at 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: zapconf 3957 2008-03-07 00:45:53Z tzafrir $
+#
+use strict;
+use File::Basename;
+BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); }
+
+use Zaptel;
+use Zaptel::Hardware;
+use Zaptel::Xpp;
+use Zaptel::Config::Defaults;
+
+my %default_context = (
+	FXO	=> 'from-pstn',
+	FXS	=> 'from-internal',
+	IN	=> 'astbank-input',
+	OUT	=> 'astbank-output',
+	BRI_TE	=> 'from-pstn',
+	BRI_NT	=> 'from-internal',
+	E1_TE	=> 'from-pstn',
+	T1_TE	=> 'from-pstn',
+	J1_TE	=> 'from-pstn',
+	E1_NT	=> 'from-internal',
+	T1_NT	=> 'from-internal',
+	J1_NT	=> 'from-internal',
+	);
+
+my %default_group = (
+	FXO	=> 0,
+	FXS	=> "5",
+	IN	=> '',
+	OUT	=> '',
+	BRI_TE	=> 0,
+	BRI_NT	=> 6,
+	E1_TE	=> 0,
+	T1_TE	=> 0,
+	J1_TE	=> 0,
+	E1_NT	=> 6,
+	T1_NT	=> 6,
+	J1_NT	=> 6,
+	);
+
+my $fxs_default_start = 'ls';
+
+my %default_zaptel_signalling = (
+	FXO	=> 'fxsks',
+	FXS	=> "fxo{fxs_default_start}",
+	IN	=> "fxo{fxs_default_start}",
+	OUT	=> "fxo{fxs_default_start}",
+	);
+
+my %default_zapata_signalling = (
+	FXO	=> 'fxs_ks',
+	FXS	=> "fxo_{fxs_default_start}",
+	IN	=> "fxo_{fxs_default_start}",
+	OUT	=> "fxo_{fxs_default_start}",
+	);
+
+my $base_exten = 4000;
+my $fxs_immediate = 'no';
+my $lc_country = 'us';
+my $loadzone = $lc_country;
+my $defaultzone = $lc_country;
+my $bri_sig_style = 'bri_ptmp';
+my $brint_overlap = 'no';
+
+my %zaptel_default_vars = (
+		base_exten		=> \$base_exten,
+		fxs_immediate		=> \$fxs_immediate,
+		fxs_default_start	=> \$fxs_default_start,
+		lc_country		=> [
+						\$loadzone,
+						\$defaultzone,
+					],
+		context_lines		=> \$default_context{FXO},
+		context_phones		=> \$default_context{FXS},
+		context_input		=> \$default_context{IN},
+		context_output		=> \$default_context{OUT},
+		group_phones		=> [
+						\$default_group{FXS},
+						\$default_group{IN},
+						\$default_group{OUT},
+					],
+		group_lines		=> \$default_group{FXO},
+		ZAPBRI_SIGNALLING	=> \$bri_sig_style,
+		brint_overlap		=> \$brint_overlap,
+		);
+
+sub map_zaptel_defaults {
+	my %defaults = @_;
+	foreach my $name (keys %defaults) {
+		my $val = $defaults{$name};
+		my $ref = $zaptel_default_vars{$name};
+		my $type = ref $ref;
+		my @vars = ();
+		# Some broken shells (msh) export even variables
+		# That where not defined. Work around that.
+		next unless defined $val && $val ne '';
+		if($type eq 'SCALAR') {
+			@vars = ($ref);
+		} elsif($type eq 'ARRAY') {
+			@vars = @$ref;
+		} else {
+			die "$0: Don't know how to map '$name' (type=$type)\n";
+		}
+		foreach my $v (@vars) {
+			$$v = $val;
+		}
+	}
+}
+
+
+my $zapconf_file;
+my $zapatachannels_file;
+my $asterisk_file;
+my $users_file;
+my $zapataconf_file;
+
+my %files = (
+	zaptel		=> { file => \$zapconf_file, func => \&gen_zaptelconf },
+	zapata		=> { file => \$zapatachannels_file, func => \&gen_zapatachannelsconf },
+	asterisk	=> { file => \$asterisk_file, func => \&gen_asteriskconf },
+	users		=> { file => \$users_file, func => \&gen_usersconf },
+	zapataconf	=> { file => \$zapataconf_file, func => \&gen_zapataconf },
+);
+
+my @default_files = ("zaptel", "zapata");
+
+my @spans = Zaptel::spans();
+
+sub bchan_range($) {
+	my $span = shift || die;
+	my $first_chan = ($span->chans())[0];
+	my $first_num = $first_chan->num();
+	my $range_start = $first_num;
+	my @range;
+	my $prev = undef;
+
+	die unless $span->is_digital();
+	foreach my $c (@{$span->bchan_list()}) {
+		my $curr = $c + $first_num;
+		if(!defined($prev)) {
+			$prev = $curr;
+		} elsif($curr != $prev + 1) {
+			push(@range, sprintf("%d-%d", $range_start, $prev));
+			$range_start = $curr;
+		}
+		$prev = $curr;
+	}
+	if($prev >= $first_num) {
+		push(@range, sprintf("%d-%d", $range_start, $prev));
+	}
+	return join(',', @range);
+}
+
+sub gen_zaptel_signalling($) {
+	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();
+	if($type eq 'EMPTY') {
+		printf "# channel %d, %s, no module.\n", $num, $chan->fqn;
+		return;
+	}
+	my $sig = $default_zaptel_signalling{$type} || die "unknown default zaptel signalling for chan $chan type $type";
+	if ($type eq 'IN') {
+		printf "# astbanktype: input\n";
+	} elsif ($type eq 'OUT') {
+		printf "# astbanktype: output\n";
+	}
+	printf "$sig=$num\n";
+}
+
+my $bri_te_last_timing = 1;
+
+sub gen_zaptel_digital($) {
+	my $span = shift || die;
+	my $num = $span->num() || die;
+	die "Span #$num is analog" unless $span->is_digital();
+	my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
+	my $timing;
+	my $lbo = 0;
+	my $framing = $span->framing() || die "$0: No framing information for span #$num\n";
+	my $coding =  $span->coding() || die "$0: No coding information for span #$num\n";
+	my $span_crc4 = $span->crc4();
+	$span_crc4 = (defined $span_crc4) ? ",$span_crc4" : '';
+	my $span_yellow = $span->yellow();
+	$span_yellow = (defined $span_yellow) ? ",$span_yellow" : '';
+
+	$timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++;
+	printf "span=%d,%d,%d,%s,%s%s%s\n",
+			$num,
+			$timing,
+			$lbo,
+			$framing,
+			$coding,
+			$span_crc4,
+			$span_yellow;
+	printf "# termtype: %s\n", lc($termtype);
+	printf "bchan=%s\n", bchan_range($span);
+	my $dchan = $span->dchan();
+	printf "dchan=%d\n", $dchan->num();
+}
+
+sub gen_zaptelconf($) {
+	my $file = shift || die;
+	rename "$file", "$file.bak"
+		or $! == 2	# ENOENT (No dependency on Errno.pm)
+		or die "Failed to backup old config: $!\n";
+	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
+	my $old = select F;
+	printf "# Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
+	print <<"HEAD";
+# Zaptel Configuration File
+#
+# This file is parsed by the Zaptel Configurator, ztcfg
+#
+HEAD
+	foreach my $span (@spans) {
+		printf "# Span %d: %s %s\n", $span->num, $span->name, $span->description;
+		if($span->is_digital()) {
+			gen_zaptel_digital($span);
+		} else {
+			foreach my $chan ($span->chans()) {
+				if(1 || !defined $chan->type) {
+					my $type = $chan->probe_type;
+					my $num = $chan->num;
+					die "Failed probing type for channel $num"
+						unless defined $type;
+					$chan->type($type);
+				}
+				gen_zaptel_signalling($chan);
+			}
+		}
+		print "\n";
+	}
+	print <<"TAIL";
+# Global data
+
+loadzone	= $loadzone
+defaultzone	= $defaultzone
+TAIL
+	close F;
+	select $old;
+}
+
+my %DefaultConfigs = (
+	context => 'default',
+	group => '63', # FIXME: should not be needed. 
+	overlapdial => 'no',
+	busydetect => 'no',
+	rxgain => 0,
+	txgain => 0,
+);
+
+sub reset_zapata_values {
+	foreach my $arg (@_) {
+		if (exists $DefaultConfigs{$arg}) {
+			print "$arg = $DefaultConfigs{$arg}\n";
+		} else {
+			print "$arg =\n";
+		}
+	}
+}
+
+sub gen_zapata_digital($) {
+	my $span = shift || die;
+	my $num = $span->num() || die;
+	die "Span #$num is analog" unless $span->is_digital();
+	my $type = $span->type() || die "$0: Span #$num -- unkown type\n";
+	my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
+	my $group = $default_group{"$type"};
+	my $context = $default_context{"$type"};
+	my @to_reset = qw/context group/;
+
+	die "$0: missing default group (termtype=$termtype)\n" unless defined($group);
+	die "$0: missing default context\n" unless $context;
+
+	my $sig = $span->signalling || die "missing signalling info for span #$num type $type";
+	grep($bri_sig_style eq $_, 'bri', 'bri_ptmp', 'pri') or die "unknown signalling style for BRI";
+	if($span->is_bri() and $bri_sig_style eq 'bri_ptmp') {
+		$sig .= '_ptmp';
+	}
+	if ($span->is_bri() && $termtype eq 'NT' && $brint_overlap eq 'yes') {
+		print "overlapdial = yes\n";
+		push(@to_reset, qw/overlapdial/);
+	}
+		
+	$group .= "," . (10 + $num);	# Invent unique group per span
+	printf "group=$group\n";
+	printf "context=$context\n";
+	printf "switchtype = %s\n", $span->switchtype;
+	printf "signalling = %s\n", $sig;
+	printf "channel => %s\n", bchan_range($span);
+	reset_zapata_values(@to_reset);
+}
+
+sub gen_zapata_channel($) {
+	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 $exten = $base_exten + $num;
+	my $sig = $default_zapata_signalling{$type};
+	my $context = $default_context{$type};
+	my $group = $default_group{$type};
+	my $callerid;
+	my $immediate;
+
+	return if $type eq 'EMPTY';
+	die "missing default_zapata_signalling for chan #$num type $type" unless $sig;
+	$callerid = ($type eq 'FXO')
+			? 'asreceived'
+			: sprintf "\"Channel %d\" <%04d>", $num, $exten;
+	if($type eq 'IN') {
+		$immediate = 'yes';
+	}
+	# FIXME: $immediage should not be set for 'OUT' channels, but meanwhile
+	#        it's better to be compatible with genzaptelconf
+	$immediate = 'yes' if $fxs_immediate eq 'yes' and $sig =~ /^fxo_/;
+	my $signalling = $chan->signalling;
+	$signalling = " " . $signalling if $signalling;
+	my $info = $chan->info;
+	$info = " " . $info if $info;
+	printf ";;; line=\"%d %s%s%s\"\n", $num, $chan->fqn, $signalling, $info;
+	printf "signalling=$sig\n";
+	printf "callerid=$callerid\n";
+	printf "mailbox=%04d\n", $exten unless $type eq 'FXO';
+	if(defined $group) {
+		printf "group=$group\n";
+	}
+	printf "context=$context\n";
+	printf "immediate=$immediate\n" if defined $immediate;
+	printf "channel => %d\n", $num;
+	# Reset following values to default
+	printf "callerid=\n";
+	printf "mailbox=\n" unless $type eq 'FXO';
+	if(defined $group) {
+		printf "group=\n";
+	}
+	printf "context=default\n";
+	printf "immediate=no\n" if defined $immediate;
+	print "\n";
+}
+
+sub gen_zapatachannelsconf($) {
+	my $file = shift || die;
+	rename "$file", "$file.bak"
+		or $! == 2	# ENOENT (No dependency on Errno.pm)
+		or die "Failed to backup old config: $!\n";
+	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
+	my $old = select F;
+	printf "; Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
+	print <<"HEAD";
+; Zaptel Channels Configurations (zapata.conf)
+;
+; This is not intended to be a complete zapata.conf. Rather, it is intended
+; to be #include-d by /etc/zapata.conf that will include the global settings
+;
+
+HEAD
+	foreach my $span (@spans) {
+		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
+		if($span->is_digital()) {
+			gen_zapata_digital($span);
+		} else {
+			foreach my $chan ($span->chans()) {
+				gen_zapata_channel($chan);
+			}
+		}
+		print "\n";
+	}
+	close F;
+	select $old;
+}
+
+sub gen_users_channel($) {
+	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 $exten = $base_exten + $num;
+	my $sig = $default_zapata_signalling{$type};
+	my $full_name = "$type $num";
+
+	die "missing default_zapata_signalling for chan #$num type $type" unless $sig;
+	print << "EOF";
+[$exten]
+callwaiting = yes
+context = numberplan-custom-1
+fullname = $full_name
+cid_number = $exten
+hasagent = no
+hasdirectory = no
+hasiax = no
+hasmanager = no
+hassip = no
+hasvoicemail = yes
+host = dynamic
+mailbox = $exten
+threewaycalling = yes
+vmsecret = 1234
+secret = 1234
+signalling = $sig
+zapchan = $num
+registeriax = no
+registersip = no
+canreinvite = no
+nat = no
+dtmfmode = rfc2833
+disallow = all
+allow = all
+
+EOF
+}
+
+# Shifts standard output to a file (which is actually the global 'F').
+# Saves original file as a backup.
+# Input: name of file. If it is '-', no action is taken.
+sub stdout_to_file($) {
+	my $file = shift || die;
+	return '-' if ($file eq '-');
+
+	rename "$file", "$file.bak"
+		or $! == 2	# ENOENT (No dependency on Errno.pm)
+		or die "Failed to backup old config: $!\n";
+	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
+	my $old = select F;
+
+	return $old;
+}
+
+# Shifts standard output back to the original (unless the input file 
+# was '-', in which case no action is needed).
+# Input: the original file descriptor, as returned from stdout_to_file().
+sub stdout_restore($) {
+	my $old = shift || die;
+	return '-' if ($old eq '-');
+
+	close F;
+	select $old;
+}
+
+# Provide information for VoiceRoute's Druid Zaptel wizard
+sub gen_asteriskconf($) {
+	my $file = shift || die;
+	my $old = stdout_to_file($file);
+
+	my $hardware = Zaptel::Hardware->scan;
+	foreach my $dev ($hardware->device_list) {
+		$dev->{ASTERISK_NAME} = "dev-".$dev->hardware_name;
+		print "[".$dev->asterisk_name."]\n";
+		printf "vendor = %s\n", $dev->vendor;
+		printf "product = %s\n", $dev->product;
+		printf "description = %s\n", $dev->description;
+		printf "hardware_name = %s\n", $dev->hardware_name;
+		printf "driver = %s\n", $dev->driver;
+		# TODO: indicate if driver != loaded?
+		printf "loaded = %s\n", $dev->loaded;
+		print "\n";
+	}
+
+	foreach my $span (@spans) {
+		$span->{ASTERISK_NAME} = "span-".$span->num;
+		print "[".$span->asterisk_name."]\n";
+		#next unless grep { $_ eq $span->type} ( 'FXS', 'IN', 'OUT' );
+		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
+		printf "num = %s\n", $span->num;
+		printf "type = %s\n", $span->type;
+		printf "name = %s\n", $span->name;
+		printf "description = %s\n", $span->description;
+		printf "digital = %s\n", 
+			$span->is_digital? 'yes' : 'no';
+
+		if ($span->is_digital) {
+			printf "switchtype = %s\n", $span->switchtype;
+			printf "signalling = %s\n", $span->signalling;
+			printf "channels = %s\n", bchan_range($span);
+			print "\n";
+		} else {
+			print "\n";
+			foreach my $chan ($span->chans()) {
+				my $type = $chan->type;
+				my $sig = $default_zapata_signalling{$type};
+				$chan->{ASTERISK_NAME} = "chan-".$chan->num;
+
+				print "[".$chan->asterisk_name."]\n";
+
+				printf "type = %s\n", $type;
+				printf "span = %s\n", $chan->span->asterisk_name;
+				printf "channels = %s\n", $chan->num;
+				printf "index = %s\n", $chan->index;
+				printf "name = %s\n", $chan->fqn;
+				printf "signalling = %s\n", $sig;
+				print "\n";
+			}
+		}
+	}
+
+	stdout_restore($old);
+}
+
+# generate users.conf . The specific users.conf is strictly oriented
+# towards using with the asterisk-gui .
+#
+# This code could have generated a much simpler and smaller
+# configuration file, had there been minimal level of support for
+# configuration templates in the asterisk configuration rewriting. Right
+# now Asterisk's configuration rewriting simply freaks out in the face
+# of templates: http://bugs.digium.com/11442 .
+sub gen_usersconf($) {
+	my $file = shift || die;
+	rename "$file", "$file.bak"
+		or $! == 2	# ENOENT (No dependency on Errno.pm)
+		or die "Failed to backup old config: $!\n";
+	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
+	my $old = select F;
+	print <<"HEAD";
+;!
+;! Automatically generated configuration file
+;! Filename: @{[basename($file)]} ($file)
+;! Generator: $0
+;! Creation Date: @{[scalar(localtime)]}
+;!
+[general]
+;
+; Full name of a user
+;
+fullname = New User
+;
+; Starting point of allocation of extensions
+;
+userbase = @{[$base_exten+1]}
+;
+; Create voicemail mailbox and use use macro-stdexten
+;
+hasvoicemail = yes
+;
+; Set voicemail mailbox @{[$base_exten+1]} password to 1234
+;
+vmsecret = 1234
+;
+; Create SIP Peer
+;
+hassip = no
+;
+; Create IAX friend
+;
+hasiax = no
+;
+; Create Agent friend
+;
+hasagent = no
+;
+; Create H.323 friend
+;
+;hash323 = yes
+;
+; Create manager entry
+;
+hasmanager = no
+;
+; Remaining options are not specific to users.conf entries but are general.
+;
+callwaiting = yes
+threewaycalling = yes
+callwaitingcallerid = yes
+transfer = yes
+canpark = yes
+cancallforward = yes
+callreturn = yes
+callgroup = 1
+pickupgroup = 1
+localextenlength = @{[length($base_exten)]}
+
+
+HEAD
+	foreach my $span (@spans) {
+		next unless grep { $_ eq $span->type} ( 'FXS', 'IN', 'OUT' );
+		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
+		foreach my $chan ($span->chans()) {
+			gen_users_channel($chan);
+		}
+		print "\n";
+	}
+	close F;
+	select $old;
+}
+
+sub gen_zapataconf($) {
+	my $file = shift || die;
+	open(F, ">>$file") || die "$0: Failed to open $file: $!\n";
+	my $old = select F;
+	foreach my $span (@spans) {
+		next unless $span->type eq 'FXO';
+		my $current_sig = "";
+		for my $chan ($span->chans()) {
+			my $chan_num = $chan->num;
+			if ($default_zapata_signalling{$chan->type} ne $current_sig) {
+				$current_sig = $default_zapata_signalling{$chan->type};
+				print "\nsignalling = $current_sig";
+				print "\nchannel => $chan_num";
+			} else {
+				print ",$chan_num";
+			}
+		}
+		print "\n";
+	}
+	close F;
+	select $old;
+}
+
+sub set_defaults {
+	# Source default files
+	my ($default_file, %source_defaults) =
+		Zaptel::Config::Defaults::source_vars(keys(%zaptel_default_vars));
+	map_zaptel_defaults(%source_defaults);
+	# Fixups
+	foreach my $val (values %default_zaptel_signalling, values %default_zapata_signalling) {
+		$val =~ s/{fxs_default_start}/$fxs_default_start/g;
+	}
+	$zapconf_file = $ENV{ZAPCONF_FILE} || "/etc/zaptel.conf";
+	$zapatachannels_file = $ENV{ZAPATA_FILE} || "/etc/asterisk/zapata-channels.conf";
+	$asterisk_file = $ENV{ASTERISK_FILE} || "/var/lib/asterisk/asterisk-detected-zap.conf";
+	$users_file = $ENV{USERS_FILE} || "/etc/asterisk/users.conf";
+	$zapataconf_file = $ENV{ZAPATACONF_FILE} || "/etc/asterisk/zapata.conf";
+}
+
+sub parse_args {
+	return if @ARGV == 0;
+	@default_files = ();
+	for my $file (@ARGV) {
+		die "$0: Unknown file '$file'" unless defined $files{$file};
+		push @default_files, $file;
+	}
+}
+
+sub generate_files {
+	for my $file (@default_files) {
+		&{$files{$file}->{func}}(${$files{$file}->{file}});
+	}
+}
+set_defaults;
+parse_args;
+generate_files;
+
+__END__
+
+=head1 NAME
+
+zapconf - Generate configuration for zaptel channels.
+
+=head1 SYNOPSIS
+
+zapconf [FILES...]
+
+=head1 DESCRIPTION
+
+This script generate configuration files for Zaptel hardware.
+Currently it can generate three files: zaptel, zapata, users and zapataconf (see below).
+Without arguments, it generates only zaptel and zapata.
+
+=over 4
+
+=item zaptel - /etc/zaptel.conf
+
+Configuration for ztcfg(1). It's location may be overriden by the
+environment variable ZAPCONF_FILE.
+
+=item zapata - /etc/asterisk/zapata-channels.conf
+
+Configuration for asterisk(1). It should be included in the main /etc/asterisk/zapata.conf.
+It's location may be overriden by the environment variable ZAPATA_FILE.
+
+=item users - /etc/asterisk/users.conf
+
+Configuration for asterisk(1) and AsteriskGUI.
+It's location may be overriden by the environment variable USERS_FILE.
+
+=item zapataconf - /etc/asterisk/zapata.conf
+
+Configuration for asterisk(1) and AsteriskGUI.
+It's location may be overriden by the environment variable ZAPATACONF_FILE.
+
+
+=back




More information about the Pkg-voip-commits mailing list