[zaptel-commits] tzafrir: branch tzafrir/kernelmove r2404 - in /team/tzafrir/kernelmove: ./ ke...

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Tue Apr 10 23:01:23 MST 2007


Author: tzafrir
Date: Wed Apr 11 01:01:23 2007
New Revision: 2404

URL: http://svn.digium.com/view/zaptel?view=rev&rev=2404
Log:
Merging 2314 through 2402 from trunk.

Modified:
    team/tzafrir/kernelmove/README.Linux26
    team/tzafrir/kernelmove/kernel/wct4xxp/base.c
    team/tzafrir/kernelmove/kernel/wct4xxp/wct4xxp.h
    team/tzafrir/kernelmove/kernel/xpp/utils/genzaptelconf
    team/tzafrir/kernelmove/kernel/xpp/utils/genzaptelconf.8
    team/tzafrir/kernelmove/kernel/zaptel.c
    team/tzafrir/kernelmove/zaptel.init
    team/tzafrir/kernelmove/zaptel.xml

Modified: team/tzafrir/kernelmove/README.Linux26
URL: http://svn.digium.com/view/zaptel/team/tzafrir/kernelmove/README.Linux26?view=diff&rev=2404&r1=2403&r2=2404
==============================================================================
--- team/tzafrir/kernelmove/README.Linux26 (original)
+++ team/tzafrir/kernelmove/README.Linux26 Wed Apr 11 01:01:23 2007
@@ -4,7 +4,7 @@
 can create the symlink to /lib/modules/`uname -r`/build/ and then 
 you can type:
 
-# make linux26
+# make
 # make install
 
 Note that you will also need CRC-CCITT functions compiled

Modified: team/tzafrir/kernelmove/kernel/wct4xxp/base.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/kernelmove/kernel/wct4xxp/base.c?view=diff&rev=2404&r1=2403&r2=2404
==============================================================================
--- team/tzafrir/kernelmove/kernel/wct4xxp/base.c (original)
+++ team/tzafrir/kernelmove/kernel/wct4xxp/base.c Wed Apr 11 01:01:23 2007
@@ -48,18 +48,6 @@
 #include "wct4xxp.h"
 #include "vpm450m.h"
 
-/*
- * Tasklets provide better system interactive response at the cost of the
- * possibility of losing a frame of data at very infrequent intervals.  If
- * you are more concerned with the performance of your machine, enable the
- * tasklets.  If you are strict about absolutely no drops, then do not enable
- * tasklets.
- *
- * XXX THIS IS NOT CURRENTLY IMPLEMENTED FOR THIS MODULE.  FOR NOW, DO NOT USE!
- */
-
-/* #define ENABLE_TASKLETS */
-
 /* Work queues are a way to better distribute load on SMP systems */
 #if defined(LINUX26) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
 /*
@@ -245,8 +233,6 @@
 static struct devtype wct210 = { "Wildcard TE210P ", FLAG_2NDGEN | FLAG_2PORT };
 	
 
-static int inirq = 0;
-
 struct t4;
 
 struct t4_span {
@@ -283,9 +269,9 @@
 	int frames_in;
 
 #ifdef VPM_SUPPORT
-	unsigned int dtmfactive;
-	unsigned int dtmfmask;
-	unsigned int dtmfmutemask;
+	unsigned long dtmfactive;
+	unsigned long dtmfmask;
+	unsigned long dtmfmutemask;
 	short dtmfenergy[31];
 	short dtmfdigit[31];
 #endif
@@ -305,10 +291,6 @@
 	int syncsrc;			/* active sync source */
 	struct t4_span *tspans[4];	/* Individual spans */
 	int numspans;			/* Number of spans on the card */
-#ifdef VPM_SUPPORT
-	int vpm;
-#endif	
-
 	int blinktimer;
 #ifdef FANCY_ALARM
 	int alarmpos;
@@ -321,37 +303,39 @@
 	unsigned int gpio;
 	unsigned int gpioctl;
 	int stopdma;			/* Set to stop DMA */
-	unsigned int dmactrl;
 	int e1recover;			/* E1 recovery timer */
-	dma_addr_t 	readdma;
-	dma_addr_t	writedma;
-	unsigned long memaddr;		/* Base address of card */
-	unsigned long memlen;
-	volatile unsigned int *membase;	/* Base address of card */
+	spinlock_t reglock;		/* lock register access */
 	int spansstarted;		/* number of spans started */
-	/* spinlock_t lock; */		/* lock context */
-	spinlock_t reglock;		/* lock register access */
 	volatile unsigned int *writechunk;					/* Double-word aligned write memory */
 	volatile unsigned int *readchunk;					/* Double-word aligned read memory */
 	unsigned short canary;
 #ifdef ENABLE_WORKQUEUES
 	atomic_t worklist;
 	struct workqueue_struct *workq;
-#else
-#ifdef ENABLE_TASKLETS
-	int taskletrun;
-	int taskletsched;
-	int taskletpending;
-	int taskletexec;
-	int txerrors;
-	struct tasklet_struct t4_tlet;
-#endif
 #endif
 	unsigned int passno;	/* number of interrupt passes */
 	char *variety;
 	int last0;		/* for detecting double-missed IRQ */
 	int checktiming;	/* Set >0 to cause the timing source to be checked */
+
+	/* DMA related fields */
+	unsigned int dmactrl;
+	dma_addr_t 	readdma;
+	dma_addr_t	writedma;
+	unsigned long memaddr;		/* Base address of card */
+	unsigned long memlen;
+	volatile unsigned int *membase;	/* Base address of card */
+
+	/* Flags for our bottom half */
+	unsigned long checkflag;
+	struct tasklet_struct t4_tlet;
+	unsigned int vpm400checkstatus;
+	
+#ifdef VPM_SUPPORT
 	struct vpm450m *vpm450m;
+	int vpm;
+#endif	
+
 };
 
 #define T4_VPM_PRESENT (1 << 28)
@@ -405,9 +389,7 @@
 
 #define MAX_T4_CARDS 64
 
-#ifdef ENABLE_TASKLETS
-static void t4_tasklet(unsigned long data);
-#endif
+static void t4_isr_bh(unsigned long data);
 
 static struct t4 *cards[MAX_T4_CARDS];
 
@@ -541,13 +523,13 @@
 static inline void __t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
 {
 	unit &= 0x3;
-	if (debug & DEBUG_REGS)
+	if (unlikely(debug & DEBUG_REGS))
 		printk("Writing %02x to address %02x of unit %d\n", value, addr, unit);
 	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
 	__t4_pci_out(wc, WC_LDATA, value);
 	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LWRITE);
 	__t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));	
-	if (debug & DEBUG_REGS) printk("Write complete\n");
+	if (unlikely(debug & DEBUG_REGS)) printk("Write complete\n");
 #if 0
 	if ((addr != FRMR_TXFIFO) && (addr != FRMR_CMDR) && (addr != 0xbc))
 	{ unsigned int tmp;
@@ -746,11 +728,11 @@
 		if (debug)
 			printk("Got tone %s of '%c' on channel %d of span %d\n",
 				(start ? "START" : "STOP"), tone, channel, span + 1);
-		if ((wc->tspans[span]->dtmfmask & (1 << channel)) && (tone != 'u')) {
+		if (test_bit(channel, &wc->tspans[span]->dtmfmask) && (tone != 'u')) {
 			if (start) {
 				/* The octasic is supposed to mute us, but...  Yah, you
 				   guessed it.  */
-				if (wc->tspans[span]->dtmfmutemask & (1 << channel)) {
+				if (test_bit(channel, &wc->tspans[span]->dtmfmutemask)) {
 					unsigned long flags;
 					struct zt_chan *chan = &wc->tspans[span]->span.chans[channel];
 					int y;
@@ -761,10 +743,10 @@
 					}
 					spin_unlock_irqrestore(&chan->lock, flags);
 				}
-				wc->tspans[span]->dtmfactive |= (1 << channel);
+				set_bit(channel, &wc->tspans[span]->dtmfactive);
 				zt_qevent_lock(&wc->tspans[span]->span.chans[channel], (ZT_EVENT_DTMFDOWN | tone));
 			} else {
-				wc->tspans[span]->dtmfactive &= ~(1 << channel);
+				clear_bit(channel, &wc->tspans[span]->dtmfactive);
 				zt_qevent_lock(&wc->tspans[span]->span.chans[channel], (ZT_EVENT_DTMFUP | tone));
 			}
 		}
@@ -811,15 +793,15 @@
 					energy = ZT_XLAW(energy, ts->chans);
 					ts->dtmfenergy[base] = energy;
 				}
-				ts->dtmfactive |= (1 << base);
+				set_bit(base, &ts->dtmfactive);
 				if (ts->dtmfdigit[base]) {
 					if (ts->dtmfmask & (1 << base))
 						zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base]));
 				}
 				ts->dtmfdigit[base] = digit;
-				if (ts->dtmfmask & (1 << base))
+				if (test_bit(base, &ts->dtmfmask))
 					zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFDOWN | digit));
-				if (ts->dtmfmutemask & (1 << base)) {
+				if (test_bit(base, &ts->dtmfmutemask)) {
 					/* Mute active receive buffer*/
 					unsigned long flags;
 					struct zt_chan *chan = &ts->span.chans[base];
@@ -855,9 +837,9 @@
 
 				if (!wc->t1e1)
 					base -= 4;
-				ts->dtmfactive &= ~(1 << base);
+				clear_bit(base, &ts->dtmfactive);
 				if (ts->dtmfdigit[base]) {
-					if (ts->dtmfmask & (1 << base))
+					if (test_bit(base, &ts->dtmfmask))
 						zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base]));
 				}
 				digit = ts->dtmfdigit[base];
@@ -1170,13 +1152,13 @@
 		if (j && (vpmdtmfsupport == 0))
 			return -ENOSYS;
 		if (j & ZT_TONEDETECT_ON)
-			ts->dtmfmask |= (1 << (chan->chanpos - 1));
+			set_bit(chan->chanpos - 1, &ts->dtmfmask);
 		else
-			ts->dtmfmask &= ~(1 << (chan->chanpos - 1));
+			clear_bit(chan->chanpos - 1, &ts->dtmfmask);
 		if (j & ZT_TONEDETECT_MUTE)
-			ts->dtmfmutemask |= (1 << (chan->chanpos - 1));
+			set_bit(chan->chanpos - 1, &ts->dtmfmutemask);
 		else
-			ts->dtmfmutemask &= ~(1 << (chan->chanpos - 1));
+			clear_bit(chan->chanpos - 1, &ts->dtmfmutemask);
 		if (wc->vpm450m) {
 			channel = (chan->chanpos) << 2;
 			if (!wc->t1e1)
@@ -2183,12 +2165,12 @@
 {
 #ifdef VPM_SUPPORT
 	int y;
-	unsigned int merged;
+	unsigned long merged;
 	merged = ts->dtmfactive & ts->dtmfmutemask;
 	if (merged) {
 		for (y=0;y<ts->span.channels;y++) {
 			/* Mute any DTMFs which are supposed to be muted */
-			if (merged & (1 << y))  {
+			if (test_bit(y, &merged)) {
 				memset(ts->span.chans[y].readchunk, ZT_XLAW(0, (ts->span.chans + y)), ZT_CHUNKSIZE);
 			}
 		}
@@ -2729,9 +2711,9 @@
 		printk("Pre-interrupt\n");
 #endif
 	
-	inirq = 1;
 	/* Make sure it's really for us */
-	status = t4_pci_in(wc, WC_INTR);
+	status = __t4_pci_in(wc, WC_INTR);
+
 	/* Process framer interrupts */
 	status2 = t4_framer_in(wc, 0, FRMR_CIS);
 	if (status2 & 0x0f) {
@@ -2751,7 +2733,7 @@
 		return;
 #endif		
 
-	t4_pci_out(wc, WC_INTR, 0);
+	__t4_pci_out(wc, WC_INTR, 0);
 
 	if (!wc->spansstarted) {
 		printk("Not prepped yet!\n");
@@ -2814,28 +2796,51 @@
 }
 #endif
 
-
-ZAP_IRQ_HANDLER(t4_interrupt_gen2)
-{
-	struct t4 *wc = dev_id;
+static void t4_isr_bh(unsigned long data)
+{
+	struct t4 *wc = (struct t4 *)data;
 	unsigned long flags;
 	unsigned char cis;
-	int x;
-	int needcheckvpm450=0;
+
+	if (test_and_clear_bit(T4_CHECK_FRAMER, &wc->checkflag)) {
+		spin_lock_irqsave(&wc->reglock, flags);
+		cis = __t4_framer_in(wc, 0, FRMR_CIS);
+		if (cis & FRMR_CIS_GIS1)
+			__t4_framer_interrupt(wc, 0);
+		if (cis & FRMR_CIS_GIS2)
+			__t4_framer_interrupt(wc, 1);
+		if (cis & FRMR_CIS_GIS3)
+			__t4_framer_interrupt(wc, 2);
+		if (cis & FRMR_CIS_GIS4)
+			__t4_framer_interrupt(wc, 3);
+		spin_unlock_irqrestore(&wc->reglock, flags);
+	}
+
+#ifdef VPM_SUPPORT
+	if (wc->vpm) {
+		if (test_and_clear_bit(T4_CHECK_VPM, &wc->checkflag)) {
+			if (wc->vpm450m) {
+				/* How stupid is it that the octasic can't generate an
+				   interrupt when there's a tone, in spite of what their
+				   documentation says? */
+				t4_check_vpm450(wc);
+			} else {
+				spin_lock_irqsave(&wc->reglock, flags);
+				__t4_check_vpm400(wc, wc->vpm400checkstatus);
+				spin_unlock_irqrestore(&wc->reglock, flags);
+			}
+		}
+	}
+#endif
+}
+
+ZAP_IRQ_HANDLER(t4_interrupt_gen2)
+{
+	struct t4 *wc = dev_id;
+	unsigned int status;
 	
-	unsigned int status;
-#if 0
-	unsigned int status2;
-#endif
-
-#if 0
-	if (wc->intcount < 20)
-		printk("2G: Pre-interrupt\n");
-#endif
-	
-	inirq = 1;
 	/* Make sure it's really for us */
-	status = t4_pci_in(wc, WC_INTR);
+	status = __t4_pci_in(wc, WC_INTR);
 
 	/* Ignore if it's not for us */
 	if (!(status & 0x7)) {
@@ -2847,10 +2852,10 @@
 	}
 
 #ifdef ENABLE_WORKQUEUES
-	t4_pci_out(wc, WC_INTR, status & 0x00000008);
-#endif
-
-	if (!wc->spansstarted) {
+	__t4_pci_out(wc, WC_INTR, status & 0x00000008);
+#endif
+
+	if (unlikely(!wc->spansstarted)) {
 		printk("Not prepped yet!\n");
 #ifdef LINUX26
 		return IRQ_NONE;
@@ -2860,13 +2865,12 @@
 	}
 
 	wc->intcount++;
-#if 1
-	if ((wc->intcount < 20) && debug)
+
+	if (unlikely((wc->intcount < 20) && debug))
 
 		printk("2G: Got interrupt, status = %08x, CIS = %04x\n", status, __t4_framer_in(wc, 0, FRMR_CIS));
-#endif		
-
-	if (status & 0x2) {
+
+	if (likely(status & 0x2)) {
 #ifdef ENABLE_WORKQUEUES
 		int cpus = num_online_cpus();
 		atomic_set(&wc->worklist, wc->numspans);
@@ -2893,97 +2897,33 @@
 #endif
 	}
 
-	spin_lock_irqsave(&wc->reglock, flags);
-
-	if (status & 0x2)
-		__t4_do_counters(wc);
-
-	if (polling && (status & 0x2)) {
-		x = wc->intcount & 15 /* 63 */;
-		switch(x) {
-		case 0:
-		case 1:
-		case 2:
-		case 3:
-			__t4_check_sigbits(wc, x);
-			break;
-		case 4:
-		case 5:
-		case 6:
-		case 7:
-			__t4_check_alarms(wc, x - 4);
-			break;
-		}
-	} else if (status & 0x1) {
-		cis = __t4_framer_in(wc, 0, FRMR_CIS);
-		if (cis & FRMR_CIS_GIS1)
-			__t4_framer_interrupt(wc, 0);
-		if (cis & FRMR_CIS_GIS2)
-			__t4_framer_interrupt(wc, 1);
-		if (cis & FRMR_CIS_GIS3)
-			__t4_framer_interrupt(wc, 2);
-		if (cis & FRMR_CIS_GIS4)
-			__t4_framer_interrupt(wc, 3);
-	}
-#ifdef VPM_SUPPORT
+	if (unlikely(status & 0x1))
+		set_bit(T4_CHECK_FRAMER, &wc->checkflag);
+
 	if (wc->vpm) {
-		if (!wc->vpm450m && !(wc->intcount % 16) && !(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
-			/* Check DTMF events */
-			int span = (wc->intcount >> 4) & 0x3;
-			int y;
-			short energy;
-			int offset = 1;
-			int chip;
-			int channel;
-			struct t4_span *ts = wc->tspans[span];
-			if (!wc->t1e1)
-				offset = 5;
-			if (ts->dtmfactive) {
-				for (y = 0; y < ts->span.channels; y++) {
-					if (ts->dtmfactive & (1 << y)) {
-						channel = y + offset;
-						chip = span + ((channel & 0x1) << 2);
-						/* Have an active channel, check its energy! */
-						energy = __t4_vpm_in(wc, chip, 0x58 + channel);
-						energy = ZT_XLAW(energy, ts->span.chans);
-						if (energy < (ts->dtmfenergy[y])) {
-							if (debug & DEBUG_DTMF)
-								printk("Finished digit on span %d, channel %d (energy = %02x < %02x) 'channel' %d, chip %d!\n", span, y + 1, energy, ts->dtmfenergy[y], channel, chip);
-							if (debug & DEBUG_DTMF)	
-								printk("Finished digit '%c' on channel %d of span %d\n", ts->dtmfdigit[y], y + 1, span);
-							if (ts->dtmfmask & (1 << y))
-								zt_qevent_lock(&ts->span.chans[y], (ZT_EVENT_DTMFUP | ts->dtmfdigit[y]));
-							ts->dtmfenergy[y] = 0;
-							ts->dtmfdigit[y] = 0;
-							ts->dtmfactive &= ~(1 << y);
-						} else if (energy > (ts->dtmfenergy[y])) {
-							if (debug & DEBUG_DTMF)
-								printk("Increasing digit energy on span %d, channel %d (energy = %02x > %02x)!\n", span, y + 1, energy, ts->dtmfenergy[y]);
-							ts->dtmfenergy[y] = energy;
-						}
-					}
-				}
-			}
-		} 
 		if (wc->vpm450m) {
 			/* How stupid is it that the octasic can't generate an
 			   interrupt when there's a tone, in spite of what their
 			   documentation says? */
 			if (!(wc->intcount & 0xf)) {
-				needcheckvpm450 = 1;
-			}
-		} else if ((status & 0xff00) != 0xff00)
-			__t4_check_vpm400(wc, (status & 0xff00) >> 8);
-	}
-#endif
-
-#if 1 
+				set_bit(T4_CHECK_VPM, &wc->checkflag);
+			}
+		} else if ((status & 0xff00) != 0xff00) {
+			wc->vpm400checkstatus = (status & 0xff00) >> 8;
+			set_bit(T4_CHECK_VPM, &wc->checkflag);
+		}
+	}
+
+	spin_lock(&wc->reglock);
+
+	__t4_do_counters(wc);
 	__handle_leds(wc);
-#endif
-
-	if (wc->checktiming > 0)
+
+	if (unlikely(wc->checktiming > 0)) {
 		__t4_set_timing_source_auto(wc);
-	if (wc->stopdma) {
+	}
+
+	if (unlikely(wc->stopdma)) {
 		/* Stop DMA cleanly if requested */
 		wc->dmactrl = 0x0;
 		__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
@@ -2992,15 +2932,14 @@
 		__t4_set_timing_source(wc, 4, 0, 0);
 		wc->stopdma = 0x0;
 	}
-	spin_unlock_irqrestore(&wc->reglock, flags);
-
-	if (needcheckvpm450 && (vpmdtmfsupport == 1)) {
-		t4_check_vpm450(wc);
-		needcheckvpm450 = 0;
-	}
+
+	spin_unlock(&wc->reglock);
+
+	if (unlikely(test_bit(T4_CHECK_VPM, &wc->checkflag) || test_bit(T4_CHECK_FRAMER, &wc->checkflag)))
+		tasklet_schedule(&wc->t4_tlet);
 
 #ifndef ENABLE_WORKQUEUES
-	t4_pci_out(wc, WC_INTR, 0);
+	__t4_pci_out(wc, WC_INTR, 0);
 #endif	
 #ifdef LINUX26
 	return IRQ_RETVAL(1);
@@ -3187,8 +3126,8 @@
 #endif
 
 	if (vpmdtmfsupport == -1) {
-		printk("VPM450: hardware DTMF disabled.\n");
-		vpmdtmfsupport = 0;
+		printk("VPM450: hardware DTMF enabled.\n");
+		vpmdtmfsupport = 1;
 	}
 
 	wc->vpm = T4_VPM_PRESENT;
@@ -3494,9 +3433,7 @@
 	spin_lock_irqsave(&wc->reglock, flags);
 	__t4_set_timing_source(wc,4, 0, 0);
 	spin_unlock_irqrestore(&wc->reglock, flags);
-#ifdef ENABLE_TASKLETS
-	tasklet_init(&wc->t4_tlet, t4_tasklet, (unsigned long)wc);
-#endif
+	tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc);
 	return 0;
 }
 

Modified: team/tzafrir/kernelmove/kernel/wct4xxp/wct4xxp.h
URL: http://svn.digium.com/view/zaptel/team/tzafrir/kernelmove/kernel/wct4xxp/wct4xxp.h?view=diff&rev=2404&r1=2403&r2=2404
==============================================================================
--- team/tzafrir/kernelmove/kernel/wct4xxp/wct4xxp.h (original)
+++ team/tzafrir/kernelmove/kernel/wct4xxp/wct4xxp.h Wed Apr 11 01:01:23 2007
@@ -105,5 +105,9 @@
 	unsigned char regs[NUM_REGS];
 };
 
+#define T4_CHECK_FRAMER		0
+#define T4_CHECK_VPM		1
+#define T4_UPDATE_TIMERS	2
+
 #define WCT4_GET_REGS	_IOW (ZT_CODE, 60, struct t4_regs)
 

Modified: team/tzafrir/kernelmove/kernel/xpp/utils/genzaptelconf
URL: http://svn.digium.com/view/zaptel/team/tzafrir/kernelmove/kernel/xpp/utils/genzaptelconf?view=diff&rev=2404&r1=2403&r2=2404
==============================================================================
--- team/tzafrir/kernelmove/kernel/xpp/utils/genzaptelconf (original)
+++ team/tzafrir/kernelmove/kernel/xpp/utils/genzaptelconf Wed Apr 11 01:01:23 2007
@@ -34,7 +34,7 @@
 # (redhat/centos)
 
 # /etc/default/zaptel may override the following variables
-VERSION=0.5.8
+VERSION=0.5.10
 rcsid='$Id$'
 lc_country=us
 # set to: ls, ks or gs for (Loopstart, Kewlstart and GroundStart)
@@ -59,6 +59,7 @@
 ZAPCONF_FILE=${ZAPCONF_FILE:-/etc/zaptel.conf}
 ZAPCONF_FILE_SYSTEM=$ZAPCONF_FILE
 ZAPATA_FILE=${ZAPATA_FILE:-/etc/asterisk/zapata-channels.conf}
+ZAPSCAN_FILE=${ZAPSCAN_FILE:-/etc/asterisk/zapscan.conf}
 ZAPTEL_BOOT_DEBIAN=${ZAPTEL_BOOT_DEBIAN:-/etc/default/zaptel}
 ZAPTEL_BOOT_FEDORA=${ZAPTEL_BOOT_FEDORA:-/etc/sysconfig/zaptel}
 MODLIST_FILE=/etc/modules
@@ -68,6 +69,9 @@
 # how long to wait for /dev/zap/ctl to appear? (seconds)
 DEVZAP_TIMEOUT=${DEVZAP_TIMEOUT:-20}
 ZTCFG=${ZTCFG:-/sbin/ztcfg}
+# BRI/PRI spans will be in an additional per-span group whose number
+# is SPAN_GROUP_BASE + span-number
+SPAN_GROUP_BASE=10
 
 # a temporary directory to store whatever we need to remember.
 #
@@ -77,14 +81,14 @@
 # A list of all modules:
 # - the list of modules which will be probed (in this order) if -d is used
 # - The module that will be deleted from /etc/modules , if -d -M is used
-ALL_MODULES="zaphfc qozap ztgsm wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wct1xxp wct4xxp wcte11xp wanpipe wcusb xpp_usb"
+ALL_MODULES="vzaphfc zaphfc qozap ztgsm wctdm wctdm24xxp wcfxo wcfxs pciradio tor2 torisa wcte12xp wct1xxp wct4xxp wcte11xp wanpipe wcusb xpp_usb"
 
 # What signalling to give to ZapBRI channels?
 # bri:       bri_net; bri_cpe           (Bristuffed Asterisk. No multi- support)
 # bri_ptmpi: bri_net_ptmp; bri_cpe_ptmp (Bristuffed Asterisk, multi- support)
 # pri:       pri_net; pri_cpe           (Recent Asterisk. Experimental)
-ZAPBRI_SIGNALLING=bri
-#ZAPBRI_SIGNALLING=bri_ptmp
+#ZAPBRI_SIGNALLING=bri
+ZAPBRI_SIGNALLING=bri_ptmp
 #ZAPBRI_SIGNALLING=pri
 
 # read default configuration from /etc/default/zaptel
@@ -115,6 +119,7 @@
 verbose=no
 do_restart=yes
 fxsdisable=no
+do_gen_zapscan=no
 
 span_te_timing_counter=1
 
@@ -123,7 +128,7 @@
 pri)      ZAPBRI_NET=pri_net;      ZAPBRI_CPE=pri_cpe ;;
 bri_ptmp) ZAPBRI_NET=bri_net_ptmp; ZAPBRI_CPE=bri_cpe_ptmp ;;
 *) 
-  echo >&2 "Incorrect value for ZAPBRI_SIGNALLING ($ZAPBRI_SIGNALLING). Abortring"
+	echo >&2 "Incorrect value for ZAPBRI_SIGNALLING ($ZAPBRI_SIGNALLING). Abortring"
 	exit 1
 	;;
 esac
@@ -146,10 +151,10 @@
 	# no point waiting.
 	if [ -c /dev/zap/ctl ] || ! grep -q zaptel /proc/modules ; then
 	  return
-  fi
-  say "Waiting for /dev/zap/ctl to be generated"
-  devzap_found=0
-  for i in `seq $DEVZAP_TIMEOUT`; do
+	fi
+	say "Waiting for /dev/zap/ctl to be generated"
+	devzap_found=0
+	for i in `seq $DEVZAP_TIMEOUT`; do
 		sleep 1
 		if [ -c /dev/zap/ctl ]; then
 		  devzap_found=1
@@ -157,8 +162,8 @@
 		fi
 	done
 	if [ "$devzap_found" != 1 ]; then
-	  say "Still no /dev/zap/ctl after $devzap_timeout seconds."
-	  echo >&2 "No /dev/zap/ctl: cannot run ztcfg. Aborting."
+		say "Still no /dev/zap/ctl after $devzap_timeout seconds."
+		echo >&2 "No /dev/zap/ctl: cannot run ztcfg. Aborting."
 	fi
 }
 
@@ -198,9 +203,9 @@
 
 update_module_list() {
   if   [ -f "$MODLIST_FILE" ]; then
-	  update_module_list_debian "$@"
+		update_module_list_debian "$@"
 	elif [ -f "$MODLIST_FILE_FEDORA" ]; then
-	  update_module_list_fedora "$@"
+		update_module_list_fedora "$@"
 	else
 	  die "Can't find a modules list to update. Tried: $MODLIST_FILE, $MODLIST_FILE_FEDORA. Aborting"
 	fi
@@ -251,6 +256,20 @@
 	echo >&2 "  -v: verbose"
 	echo >&2 "  -s: Stop Asterisk before running, and start it at the end."
 	echo >&2 "  -R: Don't restart asterisk in the end."
+	echo >&2 "  -z: also generate zapscan.conf for the asterisk GUI."
+}
+
+# print /etc/asterisk/zapscan.conf for the Asterisk-GUI
+# $1: port type. Currently only fxs/fxo . Note that this is the type, and
+#                not the signalling (which would be the fxo fir an fxs port.
+# $2: port number. Probably a range of ports is also allowed.
+print_zapscan_port () {
+	if [ "$do_gen_zapscan" != 'yes' ]; then return 0; fi
+
+	echo "
+[$2]
+port=$1
+"	>>$zapscan_file
 }
 
 # $1: channel number
@@ -286,12 +305,12 @@
 	else
 		method="$fxs_default_start"
 	fi
+	case "$sig" in
+	fxs) sig_name=FXO; sig_name_sc=fxo ;;
+	fxo) sig_name=FXS; sig_name_sc=fxs ;;
+	esac
 	case "$mode" in
 	list)
-		case "$sig" in
-		fxs) sig_name=FXO;;
-		fxo) sig_name=FXS;;
-		esac
 		echo $chan $sig_name $astbank_type;;
 	files)
 		# sadly, both input ports and output ports go into the same span as 
@@ -400,18 +419,7 @@
 		reset_zapata_entry $zapata_file $reset_values
 		echo ""                                          >> $zapata_file
 
-		# Keep a note of what channels we have identified
-		say "DEBUG: adding to channels list: channel: $chan, sig: $sig"
-		case "$sig" in
-		fxs)
-			echo $chan >$tmp_dir/fxo_$chan
-			say "DEBUG: FXO list now contains: `cat $tmp_dir/fxo_* |xargs`"
-			;;
-		fxo)
-			echo $chan >$tmp_dir/fxs_$chan
-			say "DEBUG: FXS list now contains: `cat $tmp_dir/fxs_* |xargs`"
-			;;
-		esac
+		print_zapscan_port "$sig_name_sc" "$chan"
 		;;
 	esac
 	
@@ -552,32 +560,6 @@
 	esac
 }
 
-# TODO: kill this function. It is now unreferenced from anywhere.
-check_tdm_sigtype() {
-	chan_num=$1
-	sig_type=$2
-	mode=$3
-	
-	case "$sig_type" in
-	fxs)chan_sig_type=fxo;;
-	fxo)chan_sig_type=fxs;;
-	esac
-
-#	print_pattern $chan_num $chan_sig_type $mode
-	
-  # if you get syntax error from this line, make sure you use 'bash' 
-  # rather than 'sh'
-	$ztcfg_cmd -c <(print_pattern $chan_num $chan_sig_type zaptel) 2>/dev/null  \
-		|| return 1
-	if head -c1 /dev/zap/$chan_num >/dev/null 2>/dev/null
-	then 
-		print_pattern $chan_num $chan_sig_type $mode
-		return 0
-	else
-		return 1
-	fi	
-}
-
 # run after the channel's entry. Used to reset all the values 
 reset_zapata_entry() {
 	conf_file="$1"; shift
@@ -595,12 +577,215 @@
 }
 
 
+# we need to preserve the permissions of existing configurations files.
+# However we also don't want to be left with incomplete configurations in 
+# case we are stopped in the middle. Thus we create a temporary file and
+# mv it to the original file only when done.
+#
+# This function gives the temporary file the permissions of the original,
+# or some sane defaults.
+#
+# The temporary file is generated here, and ths its name is passed through
+# a variable whose name is passed as a parameter (new_var).
+#
+# $1: orig_cfg_file
+# $2: new_var
+gen_tmp_conf() {
+	orig_cfg_file=$1
+	new_var=$2
+
+	eval $new_var=`mktemp -t genzaptelconf-zapata-XXXXXX` # assign by reference
+	if [ -r "$orig_cfg_file" ]; then
+		chown --reference="$orig_cfg_file" ${!new_var} 2>/dev/null
+		chmod --reference="$orig_cfg_file" ${!new_var} 2>/dev/null  
+	else
+		chmod 644 ${!new_var}
+	fi
+}
+
+# Extract information from one digital channel (one line in a /proc/zaptel 
+# file). Information is saved to $tmp_dir/span_foo variables.
+detect_digital_channel() {
+	line="$1"
+	chan_num="$2"
+	span_num="$3"
+
+	# PRI/BRI channel
+	# Rather than identifying cards by the header line, we identify 
+	# them by the channel names. This is shorter. 
+	# This also allows us to count the channel numbers and check if 
+	# we have a E1 span, a T1 span or a BRI span.
+	if [ "`cat $tmp_dir/span_begin`" = "-1" ]
+	then
+		echo $chan_num      >$tmp_dir/span_begin
+		echo $span_num      >$tmp_dir/span_num
+		# The Astribank channels provide the information of TE/NT in the channel name. So 
+		# why not use it?
+		case "$line" in
+		*XPP_BRI_TE/*) echo 'te' >$tmp_dir/span_termtype;;
+		*XPP_BRI_NT/*) echo 'nt' >$tmp_dir/span_termtype;;
+		esac
+		case "$line" in
+		*ZTHFC*/*|*ztqoz*/*|*XPP_BRI_*/*)
+			# BRI channel
+			echo 'ccs'          >$tmp_dir/span_framing
+			echo 'euroisdn'     >$tmp_dir/span_switchtype
+			if [ "`cat $tmp_dir/span_termtype`" = 'nt' 2>/dev/null ]
+			then
+				echo $ZAPBRI_NET >$tmp_dir/span_signalling 
+			else
+				echo $ZAPBRI_CPE >$tmp_dir/span_signalling
+			fi
+			;;
+		*ztgsm*/*)
+			# Junghanns's GSM cards. 
+			echo 'ccs'          >$tmp_dir/span_framing
+			#Does this mean anything?
+			echo 'gsm'          >$tmp_dir/span_signalling
+			;;
+		*TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*WP[TE]1/*)
+			# PRI span (E1/T1)
+			echo 'esf'       >$tmp_dir/span_framing
+			echo 'b8zs'      >$tmp_dir/span_coding
+			echo 'national'  >$tmp_dir/span_switchtype
+			echo 'pri_cpe'   >$tmp_dir/span_signalling
+			# an example of country-specific setup. This is probably not accurate
+			# Contributions are welcome
+			case "$lc_country" in 
+			nl)
+				# (Just an example for per-country info)
+				echo 'ccs'       >$tmp_dir/span_framing
+				echo 'ami'       >$tmp_dir/span_coding
+				#echo 'crc4'      >$tmp_dir/span_yellow
+				#echo 'euroisdn'  >$tmp_dir/span_switchtype
+				#echo 'pri_cpe'   >$tmp_dir/span_signalling
+				;;
+			il|de|au)
+				echo 'ccs'       >$tmp_dir/span_framing
+				echo 'hdb3'      >$tmp_dir/span_coding
+				echo 'crc4'      >$tmp_dir/span_yellow
+				echo 'euroisdn'  >$tmp_dir/span_switchtype
+				;;
+			cl)
+				echo 'ccs'       >$tmp_dir/span_framing
+				echo 'hdb3'      >$tmp_dir/span_coding
+				#echo 'crc4'      >$tmp_dir/span_yellow
+				echo 'national'  >$tmp_dir/span_switchtype
+				;;
+			esac
+		;;
+		esac
+	fi
+	# span_lastd is always the one before last 
+	# channel. span_bchan is the last:
+	echo $chan_num      >$tmp_dir/span_end
+}
+
+# read information from the $tmp_dir/span_foo files and generate 
+# configuration for the span and its channels.
+write_digital_config() {
+	# if the current file we checked was not of a digital span, we have
+	# nothing to do:
+	if [ "`cat $tmp_dir/span_begin`" = -1 ]; then return; fi
+
+	# read files to variables:
+	for suffix in num begin end timing lbo framing \
+		coding switchtype signalling yellow termtype
+	do
+		eval span_$suffix=`cat $tmp_dir/span_$suffix 2>/dev/null`
+	done
+
+	if [ "$span_yellow" != '' ]; then span_yellow=",$span_yellow"; fi
+	# exactly the same logic is used in asterisk's chan_zap.c.
+	# also not that $(( )) is bash-specific
+	case "$((1+ $span_end - $span_begin))" in
+	2|3|24) #ztgsm, BRI or T1
+		dchan=$span_end
+		bchans="$span_begin-$(($span_end-1))"
+		;;
+	31) #E1
+		dchan="$(($span_begin+15))"
+		bchans="$span_begin-$(($span_begin+14)),$(($span_begin+16))-$span_end"
+		if [ "$span_switchtype" = 'national' ]; then
+			# don't leave an E1 span with defective defaults:
+			span_framing=ccs
+			span_coding=hdb3
+			span_switchtype=euroisdn
+		fi
+		;;
+	esac
+	# Let's assume that a TE span should get the clock from the remote unit,
+	# and NT spans should provide timing. Just as a sane default.
+	# If we have several TE spans, the first will have priority 1, 
+	# second: 2, etc.
+	case "$span_signalling" in *_cpe*)
+		span_timing=$span_te_timing_counter
+		span_te_timing_counter=$(($span_te_timing_counter + 1))
+		;;
+	esac
+	case "$mode" in
+	files)
+		echo span=$span_num,$span_timing,$span_lbo,$span_framing,$span_coding$span_yellow >> $zaptel_file
+		# leave a comment in zaptel.conf that allows to tell if
+		# this span is TE or NT:
+		if [ "$span_termtype" != '' ]
+		then echo "# termtype: $span_termtype" >>$zaptel_file
+		fi
+		echo bchan=$bchans >>$zaptel_file
+		echo dchan=$dchan  >>$zaptel_file
+		span_group=$(($SPAN_GROUP_BASE + $span_num))
+		
+		if [ "$span_termtype" != '' ]
+		then
+			# an ISDN card's span that we know if it is in NT mode or TE mode.
+			# NT is the same as FXS for us and TE is the same as FXO
+			if [ "$span_termtype" = 'nt' ]
+			then
+				echo "callerid=\"Channels $span_begin - $span_end\" <$span_begin>" >> $zapata_file
+				reset_values="$reset_values callerid"
+				#echo "mailbox=$exten"
+				if [ "$group_manual" != "yes" ]
+				then 
+					echo "group=$group_phones,$span_group"     >> $zapata_file
+					reset_values="$reset_values group"
+				fi
+				if [ "$context_manual" != "yes" ]
+				then 
+					echo "context=$context_phones" >> $zapata_file
+				fi
+			else 
+				#echo "mailbox="
+				if [ "$group_manual" != "yes" ]
+				then 
+					echo "group=$group_lines,$span_group"      >> $zapata_file
+					reset_values="$reset_values group"
+				fi
+				if [ "$context_manual" != "yes" ]
+				then 
+					echo "context=$context_lines"  >> $zapata_file
+					reset_values="$reset_values context"
+				fi
+			fi
+		fi
+		echo "switchtype = $span_switchtype" >> $zapata_file
+		echo "signalling = $span_signalling" >> $zapata_file
+		echo "channel => $bchans"            >> $zapata_file
+		reset_zapata_entry $zapata_file $reset_values
+		reset_values=
+		;;
+	list)
+		echo "### BRI/PRI: $span_termtype" 
+		echo "$bchans Data"
+		echo "$dchan Control"
+		#echo BRI/PRI: chans: $bchans, control: $dchan
+		;;
+	esac
+}
+
+# This is where the actual detection configuration detection work happens.
 genconf() {
 	local mode=$1
 	local reset_values=""
-	# reset FXO list (global)
-	#say "DEBUG: resetting channels lists"
-	rm -f $tmp_dir/fx{s,o}_*
 
 # 	spanlist=`echo /proc/zaptel/* |  grep -v '\*'`
 # 	spanlist=$(for i in `for i in  /proc/zaptel/*; do if [ -f $i ]; then echo $i |  cut -f 4 -d / ; fi; done | sort -n`; do echo -n "/proc/zaptel/$i "; done)
@@ -613,22 +798,20 @@
 
 
 	case "$mode" in 
-		files)
-			local zaptel_file=`mktemp -t genzaptelconf-zaptel-XXXXXX`
-			local zapata_file=`mktemp -t genzaptelconf-zapata-XXXXXX`
-			if [ -r "${ZAPCONF_FILE}" ]; then
-				chown --reference="${ZAPCONF_FILE}" $zaptel_file || true
-				chmod --reference="${ZAPCONF_FILE}" $zaptel_file 
-			else
-				chmod 644 $zaptel_file 
-			fi
-			if [ -r "${ZAPATA_FILE}" ]; then
-				chown --reference="${ZAPATA_FILE}" $zapata_file || true
-				chmod --reference="${ZAPATA_FILE}" $zapata_file 
-			else
-				chmod 644 $zapata_file 
-			fi
-			cat <<EOF >$zaptel_file
+	files)
+		if [ "$do_gen_zapscan" = 'yes' ]; then
+			gen_tmp_conf "$ZAPSCAN_FILE" zapscan_file
+			cat <<EOF >$zapscan_file
+; zapscan.conf: information about detected zaptel channels
+; (currently: analog only)
+;
+; Automatically generated by $0 -- Please do not edit.
+
+EOF
+		fi
+		gen_tmp_conf "$ZAPTEL_FILE" zaptel_file
+		gen_tmp_conf "$ZAPATA_FILE" zapata_file
+		cat <<EOF >$zaptel_file
 # Autogenerated by $0 -- do not hand edit
 # Zaptel Configuration File
 #
@@ -638,7 +821,7 @@
 # It must be in the module loading order
 
 EOF
-			cat <<EOF >$zapata_file
+		cat <<EOF >$zapata_file
 ; Autogenerated by $0 -- do not hand edit
 ; Zaptel Channels Configurations (zapata.conf)
 ;
@@ -672,10 +855,10 @@
 		case "$mode" in
 		list) echo "### $title";;
 		files)
-		  echo ""         >>$zaptel_file
-		  echo "# $title" >>$zaptel_file
-		  echo ""         >>$zapata_file
-		  echo "; $title" >>$zapata_file
+			echo ""         >>$zaptel_file
+			echo "# $title" >>$zaptel_file
+			echo ""         >>$zapata_file
+			echo "; $title" >>$zapata_file
 			;;
 		esac
 		echo '-1'  >$tmp_dir/span_begin
@@ -749,74 +932,7 @@
 				print_pattern -a input $chan_num fxo $mode
 				;;
 			*ZTHFC*/*|*ztqoz*/*|*ztgsm/*|*TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*XPP_BRI_*/*|*WP[TE]1/*)
-				# PRI/BRI channel
-				# Rather than identifying cards by the header line, we identify them by the channel names
-				# This is shorter. This also allows us to count the channel numbers and check if a PRI
-				# card is E1 or T1.
-				if [ "`cat $tmp_dir/span_begin`" = "-1" ]
-				then
-					echo $chan_num      >$tmp_dir/span_begin
-					echo $span_num      >$tmp_dir/span_num
-					# The Astribank channels provide the information of TE/NT in the channel name. So 
-					# why not use it?
-					case "$line" in
-					*XPP_BRI_TE/*) echo 'te' >$tmp_dir/span_termtype;;
-					*XPP_BRI_NT/*) echo 'nt' >$tmp_dir/span_termtype;;
-					esac
-					case "$line" in
-					*ZTHFC*/*|*ztqoz*/*|*XPP_BRI_*/*)
-						# BRI channel
-						echo 'ccs'          >$tmp_dir/span_framing
-						echo 'euroisdn'     >$tmp_dir/span_switchtype
-						if [ "`cat $tmp_dir/span_termtype`" = 'nt' 2>/dev/null ]
-						then
-							echo $ZAPBRI_NET >$tmp_dir/span_signalling 
-						else
-							echo $ZAPBRI_CPE >$tmp_dir/span_signalling
-						fi
-						;;
-					*ztgsm*/*)
-						# Junghanns's GSM cards. 
-						echo 'ccs'          >$tmp_dir/span_framing
-            # what switch type? Any meaning to it?
-						echo 'gsm'          >$tmp_dir/span_signalling
-						;;
-					*TE[24]/*|*WCT1/*|*Tor2/*|*TorISA/*|*WP[TE]1/*)
-						# PRI span (E1/T1)
-						echo 'esf'       >$tmp_dir/span_framing
-						echo 'b8zs'      >$tmp_dir/span_coding
-						echo 'national'  >$tmp_dir/span_switchtype
-						echo 'pri_cpe'   >$tmp_dir/span_signalling
-						# an example of country-specific setup. This is probably not accurate
-						# Contributions are welcome
-						case "$lc_country" in 
-						nl)
-							# (Just an example for per-country info)
-							echo 'ccs'       >$tmp_dir/span_framing
-							echo 'ami'       >$tmp_dir/span_coding
-							#echo 'crc4'      >$tmp_dir/span_yellow
-							#echo 'euroisdn'  >$tmp_dir/span_switchtype
-							#echo 'pri_cpe'   >$tmp_dir/span_signalling
-							;;
-						il|de|au)
-							echo 'ccs'       >$tmp_dir/span_framing
-							echo 'hdb3'      >$tmp_dir/span_coding
-							echo 'crc4'      >$tmp_dir/span_yellow
-							echo 'euroisdn'  >$tmp_dir/span_switchtype
-							;;
-						cl)
-							echo 'ccs'       >$tmp_dir/span_framing
-							echo 'hdb3'      >$tmp_dir/span_coding
-							#echo 'crc4'      >$tmp_dir/span_yellow
-							echo 'national'  >$tmp_dir/span_switchtype
-							;;
-						esac
-					;;
-					esac
-				fi
-				# span_lastd is always the one before last 
-				# channel. span_bchan is the last:
-				echo $chan_num      >$tmp_dir/span_end
+				detect_digital_channel "$line" "$chan_num" "$span_num"
 				;;
 			'') ;;		# Empty line (after span header)
 			*) 
@@ -831,97 +947,7 @@
 		done
 		# end of part in sub-process.
 		
-		if [ "`cat $tmp_dir/span_begin`" != -1 ]
-		then # write PRI span ocnfig:
-			# read files to variables:
-			for suffix in num begin end timing lbo framing \
-				coding switchtype signalling yellow termtype
-			do
-				eval span_$suffix=`cat $tmp_dir/span_$suffix 2>/dev/null`
-			done
-			if [ "$span_yellow" != '' ]; then span_yellow=",$span_yellow"; fi
-			# exactly the same logic is used in asterisk's chan_zap.c.
-			# also not that $(( )) is bash-specific
-			case "$((1+ $span_end - $span_begin))" in
-			2|3|24) #ztgsm, BRI or T1
-			  dchan=$span_end
-				bchans="$span_begin-$(($span_end-1))"
-				;;
-			31) #E1
-				dchan="$(($span_begin+15))"
-				bchans="$span_begin-$(($span_begin+14)),$(($span_begin+16))-$span_end"
-				if [ "$span_switchtype" = 'national' ]; then
-					span_framing=ccs
-					span_coding=hdb3
-					span_switchtype=euroisdn
-				fi
-				;;
-			esac
-			# Let's assume that a TE span should get the clock from the remote unit,
-			# and NT spans should provide timing. Just as a sane default.
-			# If we have several TE spans, the first will have priority 1, 
-			# second: 2, etc.
-			case "$span_signalling" in *_cpe*)
-				span_timing=$span_te_timing_counter
-				span_te_timing_counter=$(($span_te_timing_counter + 1))
-				;;
-			esac
-			case "$mode" in
-			files)
-				echo span=$span_num,$span_timing,$span_lbo,$span_framing,$span_coding$span_yellow >> $zaptel_file
-				if [ "$span_termtype" != '' ]
-				then echo "# termtype: $span_termtype" >>$zaptel_file
-				fi
-				echo bchan=$bchans >>$zaptel_file
-				echo dchan=$dchan  >>$zaptel_file
-				
-				if [ "$span_termtype" != '' ]
-				then
-					# an ISDN card's span that we know if it is in NT mode or TE mode.
-					# NT is the same as FXS for us and TE is the same as FXO
-					if [ "$span_termtype" = 'nt' ]
-					then
-						echo "callerid=\"Channels $span_begin - $span_end\" <$span_begin>" >> $zapata_file
-						reset_values="$reset_values callerid"
-						#echo "mailbox=$exten"
-						if [ "$group_manual" != "yes" ]
-						then 
-							echo "group=$group_phones"     >> $zapata_file
-							reset_values="$reset_values group"
-						fi
-						if [ "$context_manual" != "yes" ]
-						then 
-							echo "context=$context_phones" >> $zapata_file
-						fi
-					else # we have may have set it. So reset it:
-						echo "callerid=asreceived"       >> $zapata_file
-						reset_values="$reset_values callerid"
-						#echo "mailbox="
-						if [ "$group_manual" != "yes" ]
-						then 
-							echo "group=$group_lines"      >> $zapata_file
-							reset_values="$reset_values group"
-						fi
-						if [ "$context_manual" != "yes" ]
-						then 
-							echo "context=$context_lines"  >> $zapata_file
-							reset_values="$reset_values context"
-						fi
-					fi
-				fi
-				echo "switchtype = $span_switchtype" >> $zapata_file
-				echo "signalling = $span_signalling" >> $zapata_file
-				echo "channel => $bchans"            >> $zapata_file
-				reset_zapata_entry $zapata_file $reset_values
-				;;
-			list)
-				echo "### BRI/PRI: $span_termtype" 
-				echo "$bchans Data"
-				echo "$dchan Control"
-				#echo BRI/PRI: chans: $bchans, control: $dchan
-				;;
-			esac
-		fi
+		write_digital_config
 	done
 
 	if [ "$mode" = 'files' ]
@@ -936,14 +962,18 @@
 	fi
 	
 	if [ "$mode" = 'files' ]; then
-		mv ${ZAPCONF_FILE} ${ZAPCONF_FILE}.bak
+		mv ${ZAPCONF_FILE} ${ZAPCONF_FILE}.bak 2>/dev/null
 		mv $zaptel_file ${ZAPCONF_FILE}
-		mv ${ZAPATA_FILE} ${ZAPATA_FILE}.bak
+		mv ${ZAPATA_FILE} ${ZAPATA_FILE}.bak 2>/dev/nullk
 		mv $zapata_file ${ZAPATA_FILE}
-	fi
-}
-
-while getopts 'c:de:Fhlm:MRsuv' arg
+		if [ "$do_gen_zapscan" = 'yes' ]; then
+			mv $ZAPSCAN_FILE $ZAPSCAN_FILE.bak 2>/dev/null 
+			mv $zapscan_file $ZAPSCAN_FILE
+		fi
+	fi
+}
+
+while getopts 'c:de:Fhlm:MRsuvz' arg
 do
 	case "$arg" in
 		e) # guarantee that it is a number:
@@ -959,6 +989,7 @@
 		M) do_module_list=yes; do_detect=yes ;;
 		s) force_stop_ast=yes ;;
 		R) do_restart=no ;;
+		z) do_gen_zapscan=yes ;;
 		h) usage; exit 0;;
 		*) echo >&2 "unknown parameter -$arg, Aborting"; usage; exit 1;;
 	esac
@@ -991,14 +1022,14 @@
 # make sure asterisk is not in our way
 if [ "$force_stop_ast" = 'yes' ]
 then
-  /etc/init.d/asterisk stop 1>&2
+	/etc/init.d/asterisk stop 1>&2
 else
   # if asterisk is running and we wanted to detect modules
 	# or simply to unload modules, asterisk needs to go away.
 	if ( [ "$do_unload" = yes ] || [ "$do_detect" = yes ] ) && \
-	  pidof asterisk >/dev/null 
+		pidof asterisk >/dev/null 
 	then
-	  echo >&2 "Asterisk is already running. Configuration left untouched"
+		echo >&2 "Asterisk is already running. Configuration left untouched"
 		echo >&2 "You can use the option -s to shut down Asterisk for the"
 		echo >&2 "duration of the detection."
 		exit 1
@@ -1028,17 +1059,17 @@
 
 if [ "$tmp_dir" != '' ]
 then
-  rm -rf "$tmp_dir"
+	rm -rf "$tmp_dir"
 fi
 
 if [ "$force_stop_ast" != 'yes' ] || [ "$do_restart" != 'yes' ]
 then
-  exit 0
+	exit 0
 fi
 
 if [ -x /etc/init.d/asterisk ]
 then
-  /etc/init.d/asterisk start 1>&2
+	/etc/init.d/asterisk start 1>&2
 fi
 

[... 450 lines stripped ...]


More information about the zaptel-commits mailing list