[Pkg-voip-commits] r5162 - in /asterisk/trunk/debian: changelog patches/bristuff/zapata-bri+euroisdn patches/bristuff/zapata_euroisdn_holded patches/bristuff/zapata_num_spans patches/series

tzafrir-guest at alioth.debian.org tzafrir-guest at alioth.debian.org
Mon Jan 21 15:46:53 UTC 2008


Author: tzafrir-guest
Date: Mon Jan 21 15:46:53 2008
New Revision: 5162

URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=5162
Log:
* Break bristuff BRI/EuroISDN patch: 
- zapata_num_spans - already accepted by upstream. Independent of libpri
  bristuff patch.
- zapata-bri+euroisdn - now does not depend on most bristuff interface
  changes. But lacks:
- zapata_euroisdn_holded - Support for putting an ISDN phone on hold.
  Depends on some other bristuff patches, and adds another interface change.
* patch use-libpri-bristuffed right next to zapata-bri+euroisdn, as
  zapata-bri+euroisdn depends on it to build.

Added:
    asterisk/trunk/debian/patches/bristuff/zapata_euroisdn_holded
    asterisk/trunk/debian/patches/bristuff/zapata_num_spans
Modified:
    asterisk/trunk/debian/changelog
    asterisk/trunk/debian/patches/bristuff/zapata-bri+euroisdn
    asterisk/trunk/debian/patches/series

Modified: asterisk/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/trunk/debian/changelog?rev=5162&op=diff
==============================================================================
--- asterisk/trunk/debian/changelog (original)
+++ asterisk/trunk/debian/changelog Mon Jan 21 15:46:53 2008
@@ -1,8 +1,20 @@
 asterisk (1:1.4.17~dfsg-3) UNRELEASED; urgency=low
 
+  [ Faidon Liambotis ]
   * Update debian/copyright (packaging copyright, formatting etc.)
 
- -- Faidon Liambotis <paravoid at debian.org>  Fri, 11 Jan 2008 21:45:01 +0200
+  [ Tzafrir Cohen ]
+  * Break bristuff BRI/EuroISDN patch: 
+  - zapata_num_spans - already accepted by upstream. Independent of libpri
+    bristuff patch.
+  - zapata-bri+euroisdn - now does not depend on most bristuff interface
+    changes. But lacks:
+  - zapata_euroisdn_holded - Support for putting an ISDN phone on hold.
+    Depends on some other bristuff patches, and adds another interface change.
+  * patch use-libpri-bristuffed right next to zapata-bri+euroisdn, as
+    zapata-bri+euroisdn depends on it to build.
+
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Mon, 21 Jan 2008 17:40:29 +0200
 
 asterisk (1:1.4.17~dfsg-2) unstable; urgency=low
 

Modified: asterisk/trunk/debian/patches/bristuff/zapata-bri+euroisdn
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/trunk/debian/patches/bristuff/zapata-bri%2Beuroisdn?rev=5162&op=diff
==============================================================================
--- asterisk/trunk/debian/patches/bristuff/zapata-bri+euroisdn (original)
+++ asterisk/trunk/debian/patches/bristuff/zapata-bri+euroisdn Mon Jan 21 15:46:53 2008
@@ -1,6 +1,8 @@
---- a/include/asterisk/channel.h
-+++ b/include/asterisk/channel.h
-@@ -423,6 +423,7 @@ struct ast_channel {
+Index: asterisk-14/include/asterisk/channel.h
+===================================================================
+--- asterisk-14.orig/include/asterisk/channel.h	2008-01-20 21:55:17.000000000 +0200
++++ asterisk-14/include/asterisk/channel.h	2008-01-20 21:56:58.000000000 +0200
+@@ -417,6 +417,7 @@
  	unsigned int flags;				/*!< channel flags of AST_FLAG_ type */
  	unsigned short transfercapability;		/*!< ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */
  	AST_LIST_HEAD_NOLOCK(, ast_frame) readq;
@@ -8,30 +10,10 @@
  	int alertpipe[2];
  
  	int nativeformats;				/*!< Kinds of data this channel can natively handle */
---- a/main/pbx.c
-+++ b/main/pbx.c
-@@ -5132,7 +5132,7 @@ struct app_tmp {
- };
- 
- /*! \brief run the application and free the descriptor once done */
--static void *ast_pbx_run_app(void *data)
-+void *ast_pbx_run_app(void *data)
- {
- 	struct app_tmp *tmp = data;
- 	struct ast_app *app;
---- a/include/asterisk/pbx.h
-+++ b/include/asterisk/pbx.h
-@@ -145,6 +145,8 @@ void ast_unregister_switch(struct ast_sw
-  */
- struct ast_app *pbx_findapp(const char *app);
- 
-+void *ast_pbx_run_app(void *data);
-+
- /*!
-  * \brief Execute an application
-  *
---- a/channels/chan_zap.c
-+++ b/channels/chan_zap.c
+Index: asterisk-14/channels/chan_zap.c
+===================================================================
+--- asterisk-14.orig/channels/chan_zap.c	2008-01-20 21:55:17.000000000 +0200
++++ asterisk-14/channels/chan_zap.c	2008-01-20 22:33:53.000000000 +0200
 @@ -11,6 +11,10 @@
   * the project provides a web site, mailing lists and IRC
   * channels for your use.
@@ -43,16 +25,7 @@
   * This program is free software, distributed under the terms of
   * the GNU General Public License Version 2. See the LICENSE file
   * at the top of the source tree.
-@@ -192,7 +196,7 @@ static const char config[] = "zapata.con
- #define SIG_GR303FXOKS	(0x0100000 | ZT_SIG_FXOKS)
- #define SIG_GR303FXSKS	(0x0100000 | ZT_SIG_FXSKS)
- 
--#define NUM_SPANS 		32
-+#define NUM_SPANS 		128	/*!<"32 spans", muahahaha, us alaws like to have some more... */
- #define NUM_DCHANS		4	/*!< No more than 4 d-channels */
- #define MAX_CHANNELS	672		/*!< No more than a DS3 per trunk group */
- 
-@@ -218,8 +222,6 @@ static struct ast_channel inuse;
+@@ -216,8 +220,6 @@
  #ifdef PRI_GETSET_TIMERS
  static int pritimers[PRI_MAX_TIMERS];
  #endif
@@ -61,7 +34,7 @@
  #endif
  
  /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
-@@ -237,10 +239,6 @@ AST_MUTEX_DEFINE_STATIC(iflock);
+@@ -235,10 +237,6 @@
  
  static int ifcount = 0;
  
@@ -72,7 +45,7 @@
  /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
     when it's doing something critical. */
  AST_MUTEX_DEFINE_STATIC(monlock);
-@@ -255,6 +253,7 @@ static enum ast_bridge_result zt_bridge(
+@@ -253,6 +251,7 @@
  
  static int zt_sendtext(struct ast_channel *c, const char *text);
  
@@ -80,7 +53,7 @@
  /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
  static inline int zt_get_event(int fd)
  {
-@@ -299,6 +298,27 @@ static int ringt_base = DEFAULT_RINGT;
+@@ -297,6 +296,14 @@
  #define PRI_SPAN(p) (((p) >> 8) & 0xff)
  #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
  
@@ -92,23 +65,10 @@
 +	struct zt_suspended_call *next;
 +};
 +
-+struct zt_holded_call {
-+	ast_mutex_t lock;		/* Mutex */
-+	char msn[AST_MAX_EXTENSION];	/* the MSN to which this parked call belongs */
-+	char uniqueid[AST_MAX_EXTENSION];	/* unique id of the onhold channel */
-+	int tei;
-+	int cref;
-+	int alreadyhungup;
-+	struct ast_channel *channel;
-+	struct ast_channel *bridge;
-+	q931_call *call;	/* this also covers tei mumbojumbo */
-+	struct zt_holded_call *next;
-+};
-+
  struct zt_pri {
  	pthread_t master;						/*!< Thread of master */
  	ast_mutex_t lock;						/*!< Mutex */
-@@ -312,6 +332,8 @@ struct zt_pri {
+@@ -310,6 +317,8 @@
  	int nsf;							/*!< Network-Specific Facilities */
  	int dialplan;							/*!< Dialing plan */
  	int localdialplan;						/*!< Local dialing plan */
@@ -117,7 +77,7 @@
  	char internationalprefix[10];					/*!< country access code ('00' for european dialplans) */
  	char nationalprefix[10];					/*!< area access code ('0' for european dialplans) */
  	char localprefix[20];						/*!< area access code + area code ('0'+area code for european dialplans) */
-@@ -323,6 +345,7 @@ struct zt_pri {
+@@ -321,6 +330,7 @@
  	int prilogicalspan;						/*!< Logical span number within trunk group */
  	int numchans;							/*!< Num of channels we represent */
  	int overlapdial;						/*!< In overlap dialing mode */
@@ -125,17 +85,16 @@
  	int facilityenable;						/*!< Enable facility IEs */
  	struct pri *dchans[NUM_DCHANS];					/*!< Actual d-channels */
  	int dchanavail[NUM_DCHANS];					/*!< Whether each channel is available */
-@@ -338,6 +361,9 @@ struct zt_pri {
+@@ -336,6 +346,8 @@
  	struct zt_pvt *pvts[MAX_CHANNELS];				/*!< Member channel pvt structs */
  	struct zt_pvt *crvs;						/*!< Member CRV structs */
  	struct zt_pvt *crvend;						/*!< Pointer to end of CRV structs */
 + 	struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */
-+ 	struct zt_holded_call *holded_calls; /* Calls on hold */
 +	int debugfd;
  };
  
  
-@@ -455,6 +481,8 @@ static struct zt_pvt {
+@@ -453,6 +465,8 @@
  	unsigned int echocanbridged:1;
  	unsigned int echocanon:1;
  	unsigned int faxhandled:1;			/*!< Has a fax tone already been handled? */
@@ -144,7 +103,7 @@
  	unsigned int firstradio:1;
  	unsigned int hanguponpolarityswitch:1;
  	unsigned int hardwaredtmf:1;
-@@ -468,7 +496,8 @@ static struct zt_pvt {
+@@ -466,7 +480,8 @@
  	unsigned int overlapdial:1;
  	unsigned int permcallwaiting:1;
  	unsigned int permhidecallerid:1;		/*!< Whether to hide our outgoing caller ID or not */
@@ -154,7 +113,7 @@
  	unsigned int priexclusive:1;
  	unsigned int pulse:1;
  	unsigned int pulsedial:1;			/*!< whether a pulse dial phone is detected */
-@@ -505,6 +534,7 @@ static struct zt_pvt {
+@@ -503,6 +518,7 @@
  #endif
  	char cid_num[AST_MAX_EXTENSION];
  	int cid_ton;					/*!< Type Of Number (TON) */
@@ -162,7 +121,7 @@
  	char cid_name[AST_MAX_EXTENSION];
  	char lastcid_num[AST_MAX_EXTENSION];
  	char lastcid_name[AST_MAX_EXTENSION];
-@@ -570,6 +600,8 @@ static struct zt_pvt {
+@@ -568,6 +584,8 @@
  	struct zt_pvt *bearer;
  	struct zt_pvt *realcall;
  	q931_call *call;
@@ -171,7 +130,7 @@
  	int prioffset;
  	int logicalspan;
  #endif	
-@@ -615,11 +647,14 @@ static struct zt_chan_conf zt_chan_conf_
+@@ -613,11 +631,14 @@
  			.minunused = 2,
  			.idleext = "",
  			.idledial = "",
@@ -186,7 +145,7 @@
  
  			.resetinterval = 3600
  		},
-@@ -631,6 +666,8 @@ static struct zt_chan_conf zt_chan_conf_
+@@ -629,6 +650,8 @@
  			.mohinterpret = "default",
  			.mohsuggest = "",
  			.transfertobusy = 1,
@@ -195,7 +154,7 @@
  
  			.cid_signalling = CID_SIG_BELL,
  			.cid_start = CID_START_RING,
-@@ -685,6 +722,8 @@ static int zt_indicate(struct ast_channe
+@@ -683,6 +706,8 @@
  static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
  static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
@@ -204,7 +163,7 @@
  
  static const struct ast_channel_tech zap_tech = {
  	.type = "Zap",
-@@ -717,6 +756,13 @@ static const struct ast_channel_tech zap
+@@ -714,6 +739,13 @@
  struct zt_pvt *round_robin[32];
  
  #ifdef HAVE_PRI
@@ -218,7 +177,7 @@
  static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
  {
  	int res;
-@@ -1525,12 +1571,16 @@ static void zt_enable_ec(struct zt_pvt *
+@@ -1416,12 +1448,16 @@
  	int res;
  	if (!p)
  		return;
@@ -236,7 +195,7 @@
  		return;
  	}
  	if (p->echocancel) {
-@@ -1557,7 +1607,7 @@ static void zt_train_ec(struct zt_pvt *p
+@@ -1448,7 +1484,7 @@
  {
  	int x;
  	int res;
@@ -245,7 +204,7 @@
  		x = p->echotraining;
  		res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
  		if (res)
-@@ -1918,7 +1968,12 @@ static int zt_call(struct ast_channel *a
+@@ -1809,7 +1845,12 @@
  		ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
  	p->outgoing = 1;
  
@@ -259,7 +218,7 @@
  
  	mysig = p->sig;
  	if (p->outsigmod > -1)
-@@ -2149,6 +2204,7 @@ static int zt_call(struct ast_channel *a
+@@ -2040,6 +2081,7 @@
  	case SIG_PRI:
  		/* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
  		p->dialdest[0] = '\0';
@@ -267,7 +226,7 @@
  		break;
  	default:
  		ast_log(LOG_DEBUG, "not yet implemented\n");
-@@ -2169,6 +2225,12 @@ static int zt_call(struct ast_channel *a
+@@ -2060,6 +2102,12 @@
  		const char *rr_str;
  		int redirect_reason;
  
@@ -280,7 +239,7 @@
  		c = strchr(dest, '/');
  		if (c)
  			c++;
-@@ -2191,6 +2253,7 @@ static int zt_call(struct ast_channel *a
+@@ -2082,6 +2130,7 @@
  			ast_mutex_unlock(&p->lock);
  			return -1;
  		}
@@ -288,7 +247,7 @@
  		if (mysig != SIG_FXSKS) {
  			p->dop.op = ZT_DIAL_OP_REPLACE;
  			s = strchr(c + p->stripmsd, 'w');
-@@ -2214,6 +2277,8 @@ static int zt_call(struct ast_channel *a
+@@ -2105,6 +2154,8 @@
  			pri_rel(p->pri);
  			ast_mutex_unlock(&p->lock);
  			return -1;
@@ -297,7 +256,7 @@
  		}
  		if (!(sr = pri_sr_new())) {
  			ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
-@@ -2243,7 +2308,7 @@ static int zt_call(struct ast_channel *a
+@@ -2134,7 +2185,7 @@
  		pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
  		pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
  					(p->digital ? -1 : 
@@ -306,7 +265,7 @@
  		if (p->pri->facilityenable)
  			pri_facility_enable(p->pri->pri);
  
-@@ -2507,8 +2572,10 @@ static int pri_find_dchan(struct zt_pri 
+@@ -2398,8 +2449,10 @@
  	}
  	if (newslot < 0) {
  		newslot = 0;
@@ -318,7 +277,7 @@
  	}
  	if (old && (oldslot != newslot))
  		ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
-@@ -2518,6 +2585,16 @@ static int pri_find_dchan(struct zt_pri 
+@@ -2409,6 +2462,16 @@
  }
  #endif
  
@@ -335,7 +294,7 @@
  static int zt_hangup(struct ast_channel *ast)
  {
  	int res;
-@@ -2565,8 +2642,7 @@ static int zt_hangup(struct ast_channel 
+@@ -2456,8 +2519,7 @@
  	if (option_debug)
  		ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
  		p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
@@ -345,7 +304,7 @@
  	if (index > -1) {
  		/* Real channel, do some fixup */
  		p->subs[index].owner = NULL;
-@@ -2668,6 +2744,7 @@ static int zt_hangup(struct ast_channel 
+@@ -2559,6 +2621,7 @@
  	}
  
  	if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
@@ -353,7 +312,7 @@
  		p->owner = NULL;
  		p->ringt = 0;
  		p->distinctivering = 0;
-@@ -2710,7 +2787,7 @@ static int zt_hangup(struct ast_channel 
+@@ -2601,7 +2664,7 @@
  						pri_call_set_useruser(p->call, useruser);
  #endif
  
@@ -362,7 +321,7 @@
  						p->call = NULL;
  						if (p->bearer) 
  							p->bearer->call = NULL;
-@@ -2730,7 +2807,28 @@ static int zt_hangup(struct ast_channel 
+@@ -2621,7 +2684,28 @@
  							if (atoi(cause))
  								icause = atoi(cause);
  						}
@@ -378,8 +337,8 @@
 +							ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state);
 +							icause = 16; /* Note, in pri_hangup() libpri will already override the cause */
 +						    }
-+						} 
-+						
++						}
++
 +						if (p->pri->nodetype == BRI_NETWORK_PTMP) {
 +						    if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) {
 +							if (outgoing) {
@@ -387,12 +346,12 @@
 +							}
 +						    }
 +						}
-+						
-+						
++
++
  					}
  					if (res < 0) 
  						ast_log(LOG_WARNING, "pri_disconnect failed\n");
-@@ -2914,10 +3012,14 @@ static int zt_answer(struct ast_channel 
+@@ -2805,10 +2889,14 @@
  			p->proceeding = 1;
  			res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
  			pri_rel(p->pri);
@@ -407,7 +366,7 @@
  		break;
  #endif
  	case 0:
-@@ -3554,6 +3656,15 @@ static int zt_fixup(struct ast_channel *
+@@ -3445,6 +3533,15 @@
  {
  	struct zt_pvt *p = newchan->tech_pvt;
  	int x;
@@ -423,7 +382,7 @@
  	ast_mutex_lock(&p->lock);
  	ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
  	if (p->owner == oldchan) {
-@@ -3763,8 +3874,10 @@ static void zt_handle_dtmfup(struct ast_
+@@ -3654,8 +3751,10 @@
  					pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
  					if (ast_async_goto(ast, target_context, "fax", 1))
  						ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
@@ -435,7 +394,7 @@
  			} else if (option_debug)
  				ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
  		} else if (option_debug)
-@@ -3923,7 +4036,7 @@ static struct ast_frame *zt_handle_event
+@@ -3814,7 +3913,7 @@
  				if (p->call) {
  					if (p->pri && p->pri->pri) {
  						if (!pri_grab(p, p->pri)) {
@@ -444,7 +403,7 @@
  							pri_destroycall(p->pri->pri, p->call);
  							p->call = NULL;
  							pri_rel(p->pri);
-@@ -4974,7 +5087,7 @@ static struct ast_frame  *zt_read(struct
+@@ -4865,7 +4964,7 @@
  		p->subs[index].f.data = NULL;
  		p->subs[index].f.datalen= 0;
  	}
@@ -453,19 +412,19 @@
  		/* Perform busy detection. etc on the zap line */
  		f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
  		if (f) {
-@@ -4986,8 +5099,9 @@ static struct ast_frame  *zt_read(struct
+@@ -4877,8 +4976,9 @@
  				}
  			} else if (f->frametype == AST_FRAME_DTMF) {
  #ifdef HAVE_PRI
 -				if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
 -					/* Don't accept in-band DTMF when in overlap dial mode */
 +				if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) {
-+					/* Don't accept in-band DTMF when in overlap dial mode 
++					/* Don't accept in-band DTMF when in overlap dial mode
 +					   or when in non-overlap overlapdialing mode ... */
  					f->frametype = AST_FRAME_NULL;
  					f->subclass = 0;
  				}
-@@ -5062,7 +5176,9 @@ static int zt_write(struct ast_channel *
+@@ -4953,7 +5053,9 @@
  #endif
  	/* Write a frame of (presumably voice) data */
  	if (frame->frametype != AST_FRAME_VOICE) {
@@ -476,7 +435,7 @@
  			ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
  		return 0;
  	}
-@@ -5130,7 +5246,7 @@ static int zt_indicate(struct ast_channe
+@@ -5021,7 +5123,7 @@
  		switch (condition) {
  		case AST_CONTROL_BUSY:
  #ifdef HAVE_PRI
@@ -485,7 +444,7 @@
  				chan->hangupcause = AST_CAUSE_USER_BUSY;
  				chan->_softhangup |= AST_SOFTHANGUP_DEV;
  				res = 0;
-@@ -5212,7 +5328,7 @@ static int zt_indicate(struct ast_channe
+@@ -5103,7 +5205,7 @@
  		case AST_CONTROL_CONGESTION:
  			chan->hangupcause = AST_CAUSE_CONGESTION;
  #ifdef HAVE_PRI
@@ -494,7 +453,7 @@
  				chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
  				chan->_softhangup |= AST_SOFTHANGUP_DEV;
  				res = 0;
-@@ -5406,8 +5522,12 @@ static struct ast_channel *zt_new(struct
+@@ -5297,8 +5399,12 @@
  	if (state == AST_STATE_RING)
  		tmp->rings = 1;
  	tmp->tech_pvt = i;
@@ -508,7 +467,7 @@
  		tmp->callgroup = i->callgroup;
  		tmp->pickupgroup = i->pickupgroup;
  	}
-@@ -5537,6 +5657,7 @@ static void *ss_thread(void *data)
+@@ -5428,6 +5534,7 @@
  	int len = 0;
  	int res;
  	int index;
@@ -516,7 +475,7 @@
  
  	/* in the bizarre case where the channel has become a zombie before we
  	   even get started here, abort safely
-@@ -5565,10 +5686,17 @@ static void *ss_thread(void *data)
+@@ -5456,10 +5563,17 @@
  		len = strlen(exten);
  		res = 0;
  		while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
@@ -537,7 +496,7 @@
  			if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
  				timeout = matchdigittimeout;
  			else
-@@ -6784,18 +6912,44 @@ static int handle_init_event(struct zt_p
+@@ -6675,18 +6789,44 @@
  		break;
  	case ZT_EVENT_NOALARM:
  		i->inalarm = 0;
@@ -582,7 +541,7 @@
  		/* fall thru intentionally */
  	case ZT_EVENT_ONHOOK:
  		if (i->radio)
-@@ -6839,8 +6993,10 @@ static int handle_init_event(struct zt_p
+@@ -6730,8 +6870,10 @@
  			zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
  			break;
  		case SIG_PRI:
@@ -595,7 +554,7 @@
  			break;
  		default:
  			ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
-@@ -7139,6 +7295,8 @@ static int pri_resolve_span(int *span, i
+@@ -7030,6 +7172,8 @@
  		} else {
  			if (si->totalchans == 31) { /* if it's an E1 */
  				pris[*span].dchannels[0] = 16 + offset;
@@ -604,7 +563,7 @@
  			} else {
  				pris[*span].dchannels[0] = 24 + offset;
  			}
-@@ -7391,6 +7549,11 @@ static struct zt_pvt *mkintf(int channel
+@@ -7282,6 +7426,11 @@
  							destroy_zt_pvt(&tmp);
  							return NULL;
  						}
@@ -616,7 +575,7 @@
  						if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
  							ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
  							destroy_zt_pvt(&tmp);
-@@ -7408,6 +7571,11 @@ static struct zt_pvt *mkintf(int channel
+@@ -7299,6 +7448,11 @@
  							return NULL;
  						}
  						pris[span].nodetype = conf.pri.nodetype;
@@ -628,13 +587,12 @@
  						pris[span].switchtype = myswitchtype;
  						pris[span].nsf = conf.pri.nsf;
  						pris[span].dialplan = conf.pri.dialplan;
-@@ -7416,9 +7584,14 @@ static struct zt_pvt *mkintf(int channel
+@@ -7307,9 +7461,13 @@
  						pris[span].minunused = conf.pri.minunused;
  						pris[span].minidle = conf.pri.minidle;
  						pris[span].overlapdial = conf.pri.overlapdial;
 +						pris[span].usercid = conf.pri.usercid;
 +						pris[span].suspended_calls = NULL;
-+						pris[span].holded_calls = NULL;
  						pris[span].facilityenable = conf.pri.facilityenable;
  						ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
  						ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
@@ -643,7 +601,7 @@
  						ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
  						ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
  						ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
-@@ -7554,6 +7727,7 @@ static struct zt_pvt *mkintf(int channel
+@@ -7445,6 +7603,7 @@
  		tmp->restrictcid = conf.chan.restrictcid;
  		tmp->use_callingpres = conf.chan.use_callingpres;
  		tmp->priindication_oob = conf.chan.priindication_oob;
@@ -651,7 +609,7 @@
  		tmp->priexclusive = conf.chan.priexclusive;
  		if (tmp->usedistinctiveringdetection) {
  			if (!tmp->use_callerid) {
-@@ -7833,7 +8007,7 @@ static int pri_find_empty_chan(struct zt
+@@ -7724,7 +7883,7 @@
  			break;
  		if (!backwards && (x >= pri->numchans))
  			break;
@@ -660,7 +618,7 @@
  			ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
  				pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
  			return x;
-@@ -8029,6 +8203,11 @@ static struct ast_channel *zt_request(co
+@@ -7920,6 +8079,11 @@
  					p->digital = 1;
  					if (tmp)
  						tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
@@ -672,7 +630,7 @@
  				} else {
  					ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
  				}
-@@ -8062,13 +8241,14 @@ next:
+@@ -7953,13 +8117,14 @@
  				*cause = AST_CAUSE_BUSY;
  		} else if (groupmatched) {
  			*cause = AST_CAUSE_CONGESTION;
@@ -688,66 +646,7 @@
  #ifdef HAVE_PRI
  static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
  {
-@@ -8082,6 +8262,58 @@ static struct zt_pvt *pri_find_crv(struc
- 	return NULL;
- }
- 
-+static int pri_find_tei(struct zt_pri *pri, q931_call *c, int tei)
-+{
-+	int x=0;
-+	for (x=0;x<pri->numchans;x++) {
-+		if (!pri->pvts[x]) continue;
-+		if ((pri->pvts[x]->tei == tei) && (pri->pvts[x]-> call != c)) {
-+		    return x;
-+		}
-+	}
-+	return -1;
-+}
-+
-+static struct zt_holded_call *pri_get_callonhold(struct zt_pri *pri, int cref, int tei) {
-+	struct zt_holded_call *zhc = pri->holded_calls;
-+	struct zt_holded_call *zhctemp = NULL;
-+
-+	while (zhc) {
-+	    if ((zhc->tei == tei) && ((zhc->cref == cref) || (cref == -1))) {
-+		return zhc;
-+	    }			
-+	    zhctemp = zhc;
-+	    if (zhc) zhc = zhc->next;
-+	}
-+	return NULL;	
-+}
-+
-+static int pri_destroy_callonhold(struct zt_pri *pri, struct zt_holded_call *onhold) {
-+	struct zt_holded_call *zhc = pri->holded_calls;
-+	struct zt_holded_call *zhctemp = NULL;
-+
-+	while (zhc) {
-+	    if (zhc == onhold) {
-+		if (zhctemp) {
-+		    zhctemp->next = zhc->next;
-+		    zhc = zhctemp;
-+		} else {
-+		    pri->holded_calls = zhc->next;
-+		    zhc = pri->holded_calls;
-+		    zhctemp = NULL;
-+		}
-+	    }			
-+	    zhctemp = zhc;
-+	    if (zhc) zhc = zhc->next;
-+	}
-+	if (onhold) {
-+	    free(onhold);
-+	    onhold = NULL;
-+	    return 1;	
-+	}
-+	return 0;	
-+}
-+
- 
- static int pri_find_principle(struct zt_pri *pri, int channel)
- {
-@@ -8113,7 +8345,9 @@ static int pri_find_principle(struct zt_
+@@ -8004,7 +8169,9 @@
  static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
  {
  	int x;
@@ -757,7 +656,7 @@
  	if (!c) {
  		if (principle < 0)
  			return -1;
-@@ -8141,6 +8375,7 @@ static int pri_fixup_principle(struct zt
+@@ -8032,6 +8199,7 @@
  				}
  				/* Fix it all up now */
  				pri->pvts[principle]->owner = pri->pvts[x]->owner;
@@ -765,7 +664,7 @@
  				if (pri->pvts[principle]->owner) {
  					ast_string_field_build(pri->pvts[principle]->owner, name, 
  							       "Zap/%d:%d-%d", pri->trunkgroup,
-@@ -8148,13 +8383,48 @@ static int pri_fixup_principle(struct zt
+@@ -8039,13 +8207,48 @@
  					pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
  					pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
  					pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
@@ -778,21 +677,21 @@
 +  				pri->pvts[principle]->alreadyhungup = pri->pvts[x]->alreadyhungup;
 +				pri->pvts[principle]->digital = pri->pvts[x]->digital;
 +  				pri->pvts[principle]->faxhandled = pri->pvts[x]->faxhandled;
-+  
-+  				if ((pri->nodetype == BRI_CPE_PTMP) || (pri->nodetype == BRI_CPE)) { 
++
++  				if ((pri->nodetype == BRI_CPE_PTMP) || (pri->nodetype == BRI_CPE)) {
 +  				    /* this might also apply for other pri types! */
 +  				    pri->pvts[principle]->law = pri->pvts[x]->law;
 +  				    if (ioctl(pri->pvts[principle]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &pri->pvts[principle]->law) == -1)
 +  					ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[principle]->channel, pri->pvts[principle]->law);
 +  				    res = zt_setlaw(pri->pvts[principle]->subs[SUB_REAL].zfd, pri->pvts[principle]->law);
-+  				    if (res < 0) 
++  				    if (res < 0)
 +  					ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[principle]->channel);
 +				    if (!pri->pvts[principle]->digital) {
 +  					res = set_actual_gain(pri->pvts[principle]->subs[SUB_REAL].zfd, 0, pri->pvts[principle]->rxgain, pri->pvts[principle]->txgain, pri->pvts[principle]->law);
 +  				    } else {
 +  					res = set_actual_gain(pri->pvts[principle]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[principle]->law);
 +				    }
-+				    if (res < 0) 
++				    if (res < 0)
 +  					ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[principle]->channel);
 +  				    zt_confmute(pri->pvts[x], 0);
 +  				    update_conf(pri->pvts[x]);
@@ -801,7 +700,7 @@
 +  				    zt_disable_ec(pri->pvts[x]);
 +  				    zt_setlinear(pri->pvts[x]->subs[SUB_REAL].zfd, 0);
 +  				}
-+  
++
 +  				if (pri->pvts[principle]->owner) {
 +  				    snprintf(tmpname, sizeof(tmpname), "Zap/%d-1", pri->pvts[principle]->channel);
 +  				    ast_change_name(pri->pvts[principle]->owner, tmpname);
@@ -815,7 +714,7 @@
  			}
  			return principle;
  		}
-@@ -8183,7 +8453,9 @@ static int pri_fixup_principle(struct zt
+@@ -8074,7 +8277,9 @@
  		}
  		crv = crv->next;
  	}
@@ -826,7 +725,7 @@
  	return -1;
  }
  
-@@ -8242,86 +8514,21 @@ static void *do_idle_thread(void *vchan)
+@@ -8133,86 +8338,21 @@
  #ifndef PRI_RESTART
  #error "Upgrade your libpri"
  #endif
@@ -920,7 +819,7 @@
  	do {
  		pri->resetpos++;
  	} while ((pri->resetpos < pri->numchans) &&
-@@ -8405,13 +8612,30 @@ static void apply_plan_to_number(char *b
+@@ -8296,13 +8436,30 @@
  	}
  }
  
@@ -958,7 +857,7 @@
  }
  
  static void *pri_dchannel(void *vpri)
-@@ -8591,15 +8815,44 @@ static void *pri_dchannel(void *vpri)
+@@ -8482,15 +8639,44 @@
  					/* Check for an event */
  					x = 0;
  					res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
@@ -1006,7 +905,7 @@
  					}
  				
  					if (option_debug)
-@@ -8611,8 +8864,7 @@ static void *pri_dchannel(void *vpri)
+@@ -8502,8 +8688,7 @@
  					break;
  			}
  		} else if (errno != EINTR)
@@ -1016,7 +915,7 @@
  		if (e) {
  			if (pri->debug)
  				pri_dump_event(pri->dchans[which], e);
-@@ -8625,32 +8877,86 @@ static void *pri_dchannel(void *vpri)
+@@ -8516,32 +8701,86 @@
  
  			switch (e->e) {
  			case PRI_EVENT_DCHAN_UP:
@@ -1025,14 +924,14 @@
 -				pri->dchanavail[which] |= DCHAN_UP;
 -				if (!pri->pri) pri_find_dchan(pri);
 +  				if (pri->nodetype == BRI_NETWORK_PTMP) {
-+  				    if (option_verbose > 3) 
++  				    if (option_verbose > 3)
 +  					ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
 +				    pri->dchanavail[which] |= DCHAN_UP;
 +				    if (!pri->pri) pri_find_dchan(pri);
-+  
++
 +  				    /* Note presense of D-channel */
 +  				    time(&pri->lastreset);
-+  
++
 +  				    pri->resetting = 0;
 +  				    /* Take the channels from inalarm condition */
 +  				    for (i=0; i<pri->numchans; i++)
@@ -1041,10 +940,10 @@
 +  					}
 +  				} else {
 +  				    if (pri->nodetype == BRI_CPE_PTMP) {
-+  					if (option_verbose > 3) 
++  					if (option_verbose > 3)
 +  					    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
 +  				    } else {
-+  					if (option_verbose > 1) 
++  					if (option_verbose > 1)
 +  					    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
 +  				    }
 +				    pri->dchanavail[which] |= DCHAN_UP;
@@ -1081,7 +980,7 @@
 -				pri_find_dchan(pri);
 -				if (!pri_is_up(pri)) {
 +  				if (pri->nodetype == BRI_NETWORK_PTMP) {
-+  				    if (option_verbose > 3) 
++  				    if (option_verbose > 3)
 +  					ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
 +  				    // PTMP BRIs have N dchans, handled by libpri
 +  				    if (e->gen.tei == 0) break;
@@ -1105,13 +1004,13 @@
 +  						p->tei = -1;
 +  					    }
 +  					}
-+  				    } 
++  				    }
 +  				} else {
 +  				    if (pri->nodetype == BRI_CPE_PTMP) {
-+  					if (option_verbose > 3) 
++  					if (option_verbose > 3)
 +  					    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
 +  				    } else {
-+  					if (option_verbose > 1) 
++  					if (option_verbose > 1)
 +  					    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
 +  				    }
 +				    pri->dchanavail[which] &= ~DCHAN_UP;
@@ -1120,7 +1019,7 @@
  					pri->resetting = 0;
  					/* Hangup active channels and put them in alarm mode */
  					for (i = 0; i < pri->numchans; i++) {
-@@ -8660,12 +8966,13 @@ static void *pri_dchannel(void *vpri)
+@@ -8551,12 +8790,13 @@
  								/* T309 is not enabled : hangup calls when alarm occurs */
  								if (p->call) {
  									if (p->pri && p->pri->pri) {
@@ -1135,7 +1034,7 @@
  								if (p->realcall) {
  									pri_hangup_all(p->realcall, pri);
  								} else if (p->owner)
-@@ -8674,6 +8981,7 @@ static void *pri_dchannel(void *vpri)
+@@ -8565,6 +8805,7 @@
  							p->inalarm = 1;
  						}
  					}
@@ -1143,18 +1042,18 @@
  				}
  				break;
  			case PRI_EVENT_RESTART:
-@@ -8708,8 +9016,8 @@ static void *pri_dchannel(void *vpri)
+@@ -8599,8 +8840,8 @@
  								pri_destroycall(pri->pri, pri->pvts[x]->call);
  								pri->pvts[x]->call = NULL;
  							}
 -							if (pri->pvts[chanpos]->realcall) 
 -								pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
-+							if (pri->pvts[x]->realcall) 
++							if (pri->pvts[x]->realcall)
 +								pri_hangup_all(pri->pvts[x]->realcall, pri);
   							else if (pri->pvts[x]->owner)
  								pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
  							ast_mutex_unlock(&pri->pvts[x]->lock);
-@@ -8743,7 +9051,6 @@ static void *pri_dchannel(void *vpri)
+@@ -8634,7 +8875,6 @@
  					}
  				}
  				break;
@@ -1162,11 +1061,11 @@
  			case PRI_EVENT_INFO_RECEIVED:
  				chanpos = pri_find_principle(pri, e->ring.channel);
  				if (chanpos < 0) {
-@@ -8752,9 +9059,11 @@ static void *pri_dchannel(void *vpri)
+@@ -8643,9 +8883,11 @@
  				} else {
  					chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
  					if (chanpos > -1) {
-+//					ast_log(LOG_NOTICE, "INFO received on  channel %d/%d span %d\n", 
++//					ast_log(LOG_NOTICE, "INFO received on  channel %d/%d span %d\n",
 +//						PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
  						ast_mutex_lock(&pri->pvts[chanpos]->lock);
  						/* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
@@ -1175,7 +1074,7 @@
  							/* how to do that */
  							int digitlen = strlen(e->ring.callednum);
  							char digit;
-@@ -8766,6 +9075,14 @@ static void *pri_dchannel(void *vpri)
+@@ -8657,6 +8899,14 @@
  									zap_queue_frame(pri->pvts[chanpos], &f, pri);
  								}
  							}
@@ -1186,11 +1085,11 @@
 +							    } else {
 +								tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
 +							    }
-+							} 
++							}
  						}
  						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
  					}
-@@ -8773,36 +9090,59 @@ static void *pri_dchannel(void *vpri)
+@@ -8664,36 +8914,59 @@
  				break;
  			case PRI_EVENT_RING:
  				crv = NULL;
@@ -1221,14 +1120,14 @@
 -							ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
 +					    /* safety check, for messed up retransmissions? */
 +					    if (pri->pvts[chanpos]->call == e->ring.call) {
-+						ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
++						ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n",
  								PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
 -							break;
 +						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
 +						chanpos = -1;
 +						break;
 +					    } else {
-+ 						ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n", 
++ 						ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n",
 +						PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
 +						if (pri->pvts[chanpos]->realcall) {
 + 							pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
@@ -1266,7 +1165,7 @@
  					if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
  						/* Should be safe to lock CRV AFAIK while bearer is still locked */
  						crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
-@@ -8816,13 +9156,14 @@ static void *pri_dchannel(void *vpri)
+@@ -8707,13 +8980,14 @@
  								ast_log(LOG_WARNING, "Call received for busy CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
  							} else
  								ast_log(LOG_NOTICE, "Call received for unconfigured CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
@@ -1282,7 +1181,7 @@
  					pri->pvts[chanpos]->call = e->ring.call;
  					apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
  					if (pri->pvts[chanpos]->use_callerid) {
-@@ -8847,34 +9188,82 @@ static void *pri_dchannel(void *vpri)
+@@ -8738,34 +9012,82 @@
  					}
  					apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
  							     e->ring.redirectingnum, e->ring.callingplanrdnis);
@@ -1334,7 +1233,7 @@
 +  						    pri->pvts[chanpos]->exten[0] = '\0';
 +  						}
 +  					    } else {
-+  						if (pri->nodetype == BRI_CPE) { 
++  						if (pri->nodetype == BRI_CPE) {
 +  						    /* fix for .at p2p bri lines */
 +  						    pri->pvts[chanpos]->exten[0] = 's';
 +  						    pri->pvts[chanpos]->exten[1] = '\0';
@@ -1383,7 +1282,7 @@
  					/* Make sure extension exists (or in overlap dial mode, can exist) */
  					if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
  						ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
-@@ -8893,19 +9282,36 @@ static void *pri_dchannel(void *vpri)
+@@ -8784,19 +9106,36 @@
  						res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
  						if (res < 0) 
  							ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
@@ -1423,7 +1322,7 @@
  						/* Get the use_callingpres state */
  						pri->pvts[chanpos]->callingpres = e->ring.callingpres;
  					
-@@ -8917,10 +9323,17 @@ static void *pri_dchannel(void *vpri)
+@@ -8808,10 +9147,17 @@
  								/* Set bearer and such */
  								pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
  								c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
@@ -1441,7 +1340,7 @@
  							}
  
  							ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-@@ -8928,6 +9341,16 @@ static void *pri_dchannel(void *vpri)
+@@ -8819,6 +9165,16 @@
  							if (!ast_strlen_zero(e->ring.callingsubaddr)) {
  								pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
  							}
@@ -1458,7 +1357,7 @@
  							if (e->ring.ani2 >= 0) {
  								snprintf(ani2str, 5, "%.2d", e->ring.ani2);
  								pbx_builtin_setvar_helper(c, "ANI2", ani2str);
-@@ -8951,8 +9374,8 @@ static void *pri_dchannel(void *vpri)
+@@ -8842,8 +9198,8 @@
  							pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  							if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
  								if (option_verbose > 2)
@@ -1469,7 +1368,7 @@
  										pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
  							} else {
  								ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
-@@ -8960,15 +9383,19 @@ static void *pri_dchannel(void *vpri)
+@@ -8851,15 +9207,19 @@
  								if (c)
  									ast_hangup(c);
  								else {
@@ -1480,7 +1379,7 @@
  							}
  							pthread_attr_destroy(&attr);
  						} else  {
-+							/* overlapdial = no */    
++							/* overlapdial = no */
  							ast_mutex_unlock(&pri->lock);
  							/* Release PRI lock while we create the channel */
  							c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
@@ -1490,14 +1389,14 @@
  							if (c) {
  								char calledtonstr[10];
  
-@@ -8995,26 +9422,43 @@ static void *pri_dchannel(void *vpri)
+@@ -8886,26 +9246,43 @@
  								ast_mutex_lock(&pri->lock);
  
  								if (option_verbose > 2)
 -									ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
 -										plancallingnum, pri->pvts[chanpos]->exten, 
 + 									ast_verbose(VERBOSE_PREFIX_3 "Accepting %s call from '%s' to '%s' on channel %d/%d, span %d\n",
-+ 										pri->pvts[chanpos]->digital ? "data" : "voice", e->ring.callingnum, pri->pvts[chanpos]->exten, 
++ 										pri->pvts[chanpos]->digital ? "data" : "voice", e->ring.callingnum, pri->pvts[chanpos]->exten,
  											pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
  								zt_enable_ec(pri->pvts[chanpos]);
 + 							    if(!ast_strlen_zero(e->ring.callingsubaddr)) {
@@ -1538,7 +1437,7 @@
  						pri->pvts[chanpos]->call = NULL;
  						pri->pvts[chanpos]->exten[0] = '\0';
  					}
-@@ -9023,9 +9467,9 @@ static void *pri_dchannel(void *vpri)
+@@ -8914,9 +9291,9 @@
  					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
  				} else {
  					if (e->ring.flexible)
@@ -1550,7 +1449,7 @@
  				}
  				break;
  			case PRI_EVENT_RINGING:
-@@ -9041,7 +9485,7 @@ static void *pri_dchannel(void *vpri)
+@@ -8932,7 +9309,7 @@
  					} else {
  						ast_mutex_lock(&pri->pvts[chanpos]->lock);
  						if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
@@ -1559,7 +1458,7 @@
  							pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
  							pri->pvts[chanpos]->alerting = 1;
  						} else
-@@ -9073,9 +9517,16 @@ static void *pri_dchannel(void *vpri)
+@@ -8964,9 +9341,16 @@
  				}
  				break;
  			case PRI_EVENT_PROGRESS:
@@ -1577,20 +1476,20 @@
  #ifdef PRI_PROGRESS_MASK
  					if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
  #else
-@@ -9122,6 +9573,12 @@ static void *pri_dchannel(void *vpri)
+@@ -9013,6 +9397,12 @@
  			case PRI_EVENT_PROCEEDING:
  				chanpos = pri_find_principle(pri, e->proceeding.channel);
  				if (chanpos > -1) {
 + 				    chanpos = pri_fixup_principle(pri, chanpos, e->proceeding.call);
 + 				    if (chanpos < 0) {
-+ 					ast_log(LOG_WARNING, "Received PROCEEDING on channel %d/%d not in use on span %d\n", 
++ 					ast_log(LOG_WARNING, "Received PROCEEDING on channel %d/%d not in use on span %d\n",
 +						PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span);
 + 					chanpos = -1;
 + 				    } else {
  					if (!pri->pvts[chanpos]->proceeding) {
  						struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
  						
-@@ -9169,6 +9626,295 @@ static void *pri_dchannel(void *vpri)
+@@ -9060,6 +9450,163 @@
  					}
  				}
  				break;				
@@ -1642,7 +1541,7 @@
 +				    break;
 +				}
 +				chanpos = pri_find_empty_chan(pri, 1);
-+				if (chanpos < 0) { 
++				if (chanpos < 0) {
 +					pri_resume_reject(pri->pri, e->resume_req.call,"All channels busy");
 +					ast_log(LOG_WARNING, "Resume requested on odd channel number %d span %d\n", chanpos, pri->span);
 +					chanpos = -1;
@@ -1674,7 +1573,7 @@
 +					// uhh ohh...what shall we do without the bearer cap???
 +						law = ZT_LAW_ALAW;
 +						res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
-+						if (res < 0) 
++						if (res < 0)
 +						    ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
 +						if (!pri->pvts[chanpos]->digital) {
 +						    res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
@@ -1726,167 +1625,35 @@
 +				    pri_hold_reject(pri->pri, e->hold_req.call);
 +				    break;
 +				}
-+				chanpos = pri_find_principle(pri, e->hold_req.channel);
-+				if (chanpos < 0)  {
-+					ast_log(LOG_WARNING, "Hold requested on unconfigured channel %d span %d\n", chanpos, pri->span);
-+					chanpos = -1;
-+				}
-+				if (chanpos > -1) {
-+				//    ast_log(LOG_NOTICE, "Hold request for channel number %d span %d\n", chanpos, pri->span);
-+				    ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ 				    if (pri->pvts[chanpos]->owner) {
-+					struct zt_pvt *p = pri->pvts[chanpos];
-+					struct zt_holded_call *zhc;
-+					int holdacked=0;
-+					
-+//					ast_log(LOG_NOTICE,"HOLD request from channel %s tei %d\n",p->owner->name, e->hold_req.tei);
-+				    	if (ast_bridged_channel(p->owner)) {
-+					    zhc = malloc(sizeof(struct zt_holded_call));
-+					    if (!zhc) {
-+						ast_log(LOG_ERROR, "unable to malloc zt_holded_call\n");
-+						break;
-+					    }
-+					    memset(zhc, 0, sizeof(zhc));
-+					    strncpy(zhc->msn,  pri->pvts[chanpos]->cid_num, sizeof(zhc->msn));
-+					    strncpy(zhc->uniqueid,  ast_bridged_channel(p->owner)->uniqueid, sizeof(zhc->uniqueid));
-+					    zhc->tei = e->hold_req.tei;
-+					    zhc->cref = e->hold_req.cref;
-+					    zhc->call = e->hold_req.call;
-+					    zhc->channel = p->owner;
-+					    zhc->alreadyhungup = 0;
-+					    zhc->bridge = ast_bridged_channel(p->owner);
-+					    zhc->next = pri->holded_calls;
-+					    pri->holded_calls = zhc;
-+
-+					    /* put channel on hold */
-+					    ast_masq_hold_call(ast_bridged_channel(p->owner), p->owner);
-+
-+					    pri_hold_acknowledge(pri->pri, e->hold_req.call);
-+					    holdacked = 1;
-+					    p->call = NULL; // free the bchannel withouth destroying the call
-+					    p->tei = -1;
-+					} else {
-+					    // cant hold a non-bridge,...yet
-+					    
-+					    // make a fake channel
-+					    
-+					    // masquerade
-+					    
-+					    // put on hold
-+					    pri_hold_reject(pri->pri, e->hold_req.call);
-+					}
-+				    } else {
-+					    pri_hold_reject(pri->pri, e->hold_req.call);
-+				    }
-+				    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+				} else {
-+					pri_hold_reject(pri->pri, e->hold_req.call);
-+				}
-+				break; 
++				/* holded calls are not implemented yet */
++				pri_hold_reject(pri->pri, e->hold_req.call);
++				break;
 +			case PRI_EVENT_RETRIEVE_REQ:
 +				if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
 +				    pri_retrieve_reject(pri->pri, e->retrieve_req.call);
 +				    break;
 +				}
-+				chanpos = pri_find_empty_chan(pri, 1);
-+				if (chanpos < 0) { 
-+					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
-+					ast_log(LOG_WARNING, "Retrieve requested on odd channel number %d span %d\n", chanpos, pri->span);
-+					chanpos = -1;
-+					break;
-+				} else if (!pri->pvts[chanpos]) {
-+					ast_log(LOG_WARNING, "Retrieve requested on unconfigured channel number %d span %d\n", chanpos, pri->span);
-+					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
-+					chanpos = -1;
-+					break;
-+				}
-+				if (chanpos > -1) {
-+				    struct zt_holded_call *onhold = NULL;
-+				    int retrieved = 0;
-+				    int res = -1;
-+				    struct app_tmp *tmp;
-+				    pthread_attr_t attr;
-+				    int law;
-+
-+				    onhold = pri_get_callonhold(pri, e->retrieve_req.cref, e->retrieve_req.tei);
-+
-+				    if (!onhold) {
-+					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
-+					break;
-+				    }
-+				    ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+					// found a parked call
-+ 					law = 1;
-+					if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
-+					    ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law);
-+					// uhh ohh...what shall we do without the bearer cap???
-+					law = ZT_LAW_ALAW;
-+					res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
-+					if (res < 0) 
-+					    ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
-+					res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
-+					if (res < 0)
-+					    ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
-+					/* Start PBX */
-+					c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 0, SUB_REAL, law, PRI_TRANS_CAP_SPEECH);
-+					if (c) {
-+					    pri->pvts[chanpos]->owner = c;
-+					    pri->pvts[chanpos]->outgoing = 1; /* for not sending proceedings... */
-+					    pri->pvts[chanpos]->call = e->retrieve_req.call;
-+					    pri->pvts[chanpos]->tei = e->retrieve_req.tei;
-+				    	    zt_enable_ec(pri->pvts[chanpos]);
-+				    	    zt_train_ec(pri->pvts[chanpos]);
-+					} else {
-+					    ast_log(LOG_ERROR, "unable to start pbx\n");
-+					}
-+
-+					retrieved = 1;
-+				//	ast_log(LOG_NOTICE, "sending RETRIEVE ACK on channel %d, span %d for tei %d cref %d\n",chanpos,pri->span, e->retrieve_req.tei,  e->retrieve_req.cref);
-+					pri_retrieve_acknowledge(pri->pri, e->retrieve_req.call, chanpos + 1);
-+
-+					// the magic begins here: ....
-+					tmp = malloc(sizeof(struct app_tmp));
-+					if (tmp) {
-+					    memset(tmp, 0, sizeof(struct app_tmp));
-+					    strncpy(tmp->app, "holdedcall", sizeof(tmp->app) - 1);
-+					    strncpy(tmp->data, onhold->uniqueid, sizeof(tmp->data) - 1);
-+					    tmp->chan = c;
-+					}
-+					pri_destroy_callonhold(pri, onhold);
-+					onhold = NULL;
-+
-+					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+					pthread_attr_init(&attr);
-+					pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-+					if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
-+ 					    ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", c->name, strerror(errno));
-+					    free(tmp);
-+					    ast_hangup(c);
-+					    retrieved = 0;
-+					}
-+
-+				    if (!retrieved) {
-+					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
-+				    }
-+				}
-+ 				break; 
++				/* Holded calls are currently not supported */
++				pri_retrieve_reject(pri->pri, e->retrieve_req.call);
++				chanpos = -1;
++				break;
 +			case PRI_EVENT_DISPLAY_RECEIVED:
 +				ast_log(LOG_NOTICE, "DISPLAY IE: [ %s ] received\n",e->display.text);
 +				chanpos = pri_find_principle(pri, e->display.channel);
 +				if (chanpos < 0) {
 +				    ast_log(LOG_WARNING, "odd channel number %d span %d\n", chanpos, pri->span);
 +				    chanpos = -1;
-+				} 
++				}
 +				if (chanpos > -1) {
 +				    if (pri->pvts[chanpos]->owner) {
 +			//		ast_sendtext(pri->pvt[chanpos]->owner, e->display.text);
 +				    }
-+				}				
++				}
 +				break;
  			case PRI_EVENT_ANSWER:
  				chanpos = pri_find_principle(pri, e->answer.channel);
  				if (chanpos < 0) {
-@@ -9181,6 +9927,7 @@ static void *pri_dchannel(void *vpri)
+@@ -9072,6 +9619,7 @@
  							PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
  					} else {
  						ast_mutex_lock(&pri->pvts[chanpos]->lock);
@@ -1894,7 +1661,7 @@
  						/* Now we can do call progress detection */
  
  						/* We changed this so it turns on the DSP no matter what... progress or no progress.
-@@ -9210,11 +9957,16 @@ static void *pri_dchannel(void *vpri)
+@@ -9101,11 +9649,16 @@
  								ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
  							pri->pvts[chanpos]->dop.dialstr[0] = '\0';
  						} else if (pri->pvts[chanpos]->confirmanswer) {
@@ -1912,7 +1679,7 @@
  						}
  
  #ifdef SUPPORT_USERUSER
-@@ -9271,20 +10023,29 @@ static void *pri_dchannel(void *vpri)
+@@ -9162,20 +9715,29 @@
  								ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
  									pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
  						} else {
@@ -1949,30 +1716,19 @@
  
  #ifdef SUPPORT_USERUSER
  						if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
-@@ -9297,8 +10058,20 @@ static void *pri_dchannel(void *vpri)
+@@ -9188,8 +9750,9 @@
  
  						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
  					} else {
 -						ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
 -							PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-+ 						struct zt_holded_call *onhold = NULL;
-+						/* check calls on hold */
-+ 						onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei);
-+ 						
-+ 						if (onhold) {
-+ 						    // ast_log(LOG_NOTICE, "hangup, found cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
-+ 						    pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1);
-+ 						    pri_destroy_callonhold(pri, onhold);
-+ 						    onhold = NULL;
-+ 						} else {
-+ 						    ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
-+ 						    ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
-+  							PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-+ 						}
++						ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
++						ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
++								PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
  					}
  				} 
  				break;
-@@ -9308,15 +10081,23 @@ static void *pri_dchannel(void *vpri)
+@@ -9199,15 +9762,23 @@
  			case PRI_EVENT_HANGUP_REQ:
  				chanpos = pri_find_principle(pri, e->hangup.channel);
  				if (chanpos < 0) {
@@ -1982,7 +1738,7 @@
 +					if (pri->nodetype == BRI_NETWORK_PTMP) {
 +					    pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1);
 +					} else {
-+					    ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
++					    ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n",
 +  						PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
 +					}
 +				} else if ((pri->pvts[chanpos]->priindication_oob != 2) || (!e->hangup.inband_progress) || (!pri->pvts[chanpos]->outgoing)) {
@@ -1999,7 +1755,7 @@
  							pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
  							if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
  								pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-@@ -9343,16 +10124,86 @@ static void *pri_dchannel(void *vpri)
+@@ -9234,16 +9805,34 @@
  								if (option_verbose > 2)
  									ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
  										pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
@@ -2013,63 +1769,11 @@
 +							    	ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
 +									pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
 +							}
-+ 							if (pri->nodetype == BRI_NETWORK_PTMP) {
-+							    // check for bri transfers, not everybody uses ECT...
-+ 							    if (pri->pvts[chanpos]->owner) {
-+ 								// find on hold call
-+								struct zt_holded_call *onhold = NULL;
-+ 								struct ast_channel *transferee = NULL;
-+								int transfer_ok = 0;
-+ 
-+ 								onhold = pri_get_callonhold(pri, -1, e->hangup.tei);
-+ 
-+ 								if (onhold) {
-+								    if (pri->pvts[chanpos]->pritransfer == 2) {
-+ 									if (((pri->pvts[chanpos]->owner->_state != AST_STATE_RING) && (pri->pvts[chanpos]->owner->_state != AST_STATE_RESERVED)) || ((!ast_strlen_zero(pri->pvts[chanpos]->exten)) && (strncasecmp(pri->pvts[chanpos]->exten, "s", sizeof(pri->pvts[chanpos]->exten))))) {
-+ 								    	    transferee = ast_get_holded_call(onhold->uniqueid);
-+ 
-+ 									    if (transferee) {
-+ 										if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) {
-+ 									    	    ast_indicate(transferee, AST_CONTROL_RINGING);
-+ 										}
-+ 
-+ 										pri->pvts[chanpos]->owner->_softhangup &= ~AST_SOFTHANGUP_DEV;
-+  
-+  									        ast_mutex_unlock(&transferee->lock);
-+ 										if (ast_channel_masquerade(pri->pvts[chanpos]->owner, transferee)) {
-+ 										    ast_log(LOG_WARNING, "unable to masquerade\n");
-+ 									        } else { 
-+ 									    	    /* beware of zombies!!! */
-+										    ast_set_flag(transferee, AST_FLAG_ZOMBIE);
-+ 										    pri->pvts[chanpos]->owner = NULL;
-+ 										    pri->pvts[chanpos]->tei = -1;
-+										    transfer_ok = 1;
-+ 										}
-+ 									    }
-+									}	
-+ 								    } else if (pri->pvts[chanpos]->pritransfer == 0) {
-+									ast_log(LOG_NOTICE, "killing channel %s \n", onhold->uniqueid);
-+ 									ast_retrieve_call_to_death(onhold->uniqueid);
-+									transfer_ok = 1;
-+ 								    } else if (pri->pvts[chanpos]->pritransfer == 1) {
-+									/* we use ECT transfers, so just ignore this */
-+									transfer_ok = 0;
-+								    }
-+							
-+								    if (transfer_ok) {
-+ 									onhold->alreadyhungup = 1;	
-+ 									pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1);
-+ 									onhold = NULL;
-+								    }
-+ 								    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ 								    break;
-+                                                        	} else {
-+                                                                    pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
-+                                                                        pri->pvts[chanpos]->call = NULL;
-+                                                                        pri->pvts[chanpos]->tei = -1;
-+                                                                }
-+  							    }
-+  							}
++							if (pri->nodetype == BRI_NETWORK_PTMP) {
++								pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
++								pri->pvts[chanpos]->call = NULL;
++								pri->pvts[chanpos]->tei = -1;
++							}
  						} else {
 -							pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
 +							pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
@@ -2090,7 +1794,7 @@
  						}
  
  #ifdef SUPPORT_USERUSER
-@@ -9366,9 +10217,39 @@ static void *pri_dchannel(void *vpri)
+@@ -9257,9 +9846,27 @@
  
  						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
  					} else {
@@ -2098,19 +1802,7 @@
 + 						if (pri->nodetype != BRI_NETWORK_PTMP) {
 +  						    ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
 + 						} else {
-+ 						    // check holded_calls!!!
-+ 						    struct zt_holded_call *onhold = NULL;
-+ 
-+ 						    onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei);
-+ 
-+ 						    if (onhold) {
-+ 							    pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1);
-+ 							    ast_retrieve_call_to_death(onhold->uniqueid);
-+ 							    pri_destroy_callonhold(pri, onhold);
-+ 							    onhold = NULL;
-+ 						    } else {
-+ 							ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-+ 						    }
++							ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
 + 						}
  					}
  				} 
@@ -2131,7 +1823,7 @@
  				break;
  			case PRI_EVENT_HANGUP_ACK:
  				chanpos = pri_find_principle(pri, e->hangup.channel);
-@@ -9380,6 +10261,7 @@ static void *pri_dchannel(void *vpri)
+@@ -9271,6 +9878,7 @@
  					if (chanpos > -1) {
  						ast_mutex_lock(&pri->pvts[chanpos]->lock);
  						pri->pvts[chanpos]->call = NULL;
@@ -2139,7 +1831,7 @@
  						pri->pvts[chanpos]->resetting = 0;
  						if (pri->pvts[chanpos]->owner) {
  							if (option_verbose > 2) 
-@@ -9396,7 +10278,9 @@ static void *pri_dchannel(void *vpri)
+@@ -9287,7 +9895,9 @@
  #endif
  
  						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
@@ -2149,7 +1841,7 @@
  				}
  				break;
  			case PRI_EVENT_CONFIG_ERR:
-@@ -9486,10 +10370,22 @@ static void *pri_dchannel(void *vpri)
+@@ -9377,10 +9987,22 @@
  					ast_mutex_lock(&pri->pvts[chanpos]->lock);
  					switch (e->notify.info) {
  					case PRI_NOTIFY_REMOTE_HOLD:
@@ -2172,75 +1864,21 @@
  						f.subclass = AST_CONTROL_UNHOLD;
  						zap_queue_frame(pri->pvts[chanpos], &f, pri);
  						break;
-@@ -9497,6 +10393,77 @@ static void *pri_dchannel(void *vpri)
+@@ -9388,6 +10010,23 @@
  					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
  				}
  				break;
 + 			case PRI_EVENT_FACILITY:
-+ 				    if (e->facility.operation == 0x06) {
-+ 					struct ast_channel *chan = NULL;
-+ 					struct zt_holded_call *onhold = NULL;
-+ 					if (option_verbose > 2) {
-+ 					    ast_verbose(VERBOSE_PREFIX_3 "ECT requested by TEI %d for cref %d\n", e->facility.tei, e->facility.cref);
-+ 					}
-+ 					/* search for cref/tei in held calls */
-+ 					onhold = pri_get_callonhold(pri, e->facility.cref, e->facility.tei);
-+ 					if (onhold) {
-+ 					    chan = ast_get_holded_call(onhold->uniqueid);
-+ 					    onhold->alreadyhungup = 1;
-+ 					    onhold = NULL;
-+ 					    if (!chan) {
-+ 						/* hang up */
-+ 					        pri_hangup(pri->pri, e->facility.call, 16, -1);
-+ 						break;
-+ 					    }
-+ 					} else {
-+ 					    /* unknown cref/tei */
-+ 					    ast_log(LOG_WARNING, "did not find call on hold for cref %d tei %d\n", e->facility.tei, e->facility.cref);
-+ 					    /* hang up */
-+ 					    pri_hangup(pri->pri, e->facility.call, 16, -1);
-+ 					    break;
-+ 					}
-+ 
-+ 					/* find an active call for the same tei */
-+ 					chanpos = pri_find_tei(pri, e->facility.call, e->facility.tei);
-+ 					if (chanpos < 0) {
-+ 					    /* did not find active call, hangup call on hold */
-+ 					    if (chan) {
-+ 						ast_hangup(chan);
-+ 						chan = NULL;
-+ 					    }
-+ 					} else {
-+ 					    ast_mutex_lock(&pri->pvts[chanpos]->lock);
-+ 					    /* transfer */
-+ 					    if (pri->pvts[chanpos]->owner) {
-+ 						if (option_verbose > 3) {
-+ 						    ast_verbose(VERBOSE_PREFIX_3 "ECT: found %s on channel %d for tei %d\n", pri->pvts[chanpos]->owner->name ,chanpos, e->facility.tei);
-+ 						}
-+ 						/* pass callprogress if the channel is not up yet */
-+ 						if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) {
-+ 						    ast_indicate(chan, AST_CONTROL_RINGING);
-+ 						}
-+ 						/* unlock the channel we removed from hold */
-+ 						ast_mutex_unlock(&chan->lock);
-+ 						if (ast_channel_masquerade(pri->pvts[chanpos]->owner, chan)) {
-+ 					    	    ast_log(LOG_WARNING, "unable to masquerade\n");
-+ 						} else {
-+ 						    /* beware of zombies !!! */
-+						    ast_set_flag(chan, AST_FLAG_ZOMBIE);
-+ 						//    chan->zombie = 1;
-+ 						}
-+ 					    }
-+ 					    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-+ 					}
-+					/* disconnect */
-+ 					pri_hangup(pri->pri, e->facility.call, 16, -1);
-+ 				    } else if (e->facility.operation == 0x0D) {
++ 				    if (e->facility.operation == 0x0D) {
++				    	struct ast_channel *owner = pri->pvts[chanpos]->owner;
++
 + 					ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum);
 + 					ast_mutex_lock(&pri->pvts[chanpos]->lock);
 + 					    /* transfer */
-+ 					    if (pri->pvts[chanpos]->owner) {
-+						snprintf(pri->pvts[chanpos]->owner->call_forward, sizeof(pri->pvts[chanpos]->owner->call_forward), "Local/%s@%s", e->facility.forwardnum, pri->pvts[chanpos]->owner->context);
++ 					    if (owner) {
++						ast_string_field_build(owner, call_forward, 
++								"Local/%s@%s",  e->facility.forwardnum,
++								owner->context);
 + 					    }
 + 					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
 + 				    } else {
@@ -2250,7 +1888,7 @@
  			default:
  				ast_log(LOG_DEBUG, "Event: %d\n", e->e);
  			}
-@@ -9558,7 +10525,7 @@ static int start_pri(struct zt_pri *pri)
+@@ -9449,7 +10088,7 @@
  			pri->fds[i] = -1;
  			return -1;
  		}
@@ -2259,20 +1897,20 @@
  		/* Force overlap dial if we're doing GR-303! */
  		if (pri->switchtype == PRI_SWITCH_GR303_TMC)
  			pri->overlapdial = 1;
-@@ -9626,39 +10593,77 @@ static char *complete_span_5(const char 
+@@ -9517,39 +10156,77 @@
  
  static int handle_pri_set_debug_file(int fd, int argc, char **argv)
  {
 -	int myfd;
 + 	int myfd, x, d;
 + 	int span;
-+ 
-+ 	if (argc < 6) 
++
++ 	if (argc < 6)
 + 		return RESULT_SHOWUSAGE;
  
  	if (!strncasecmp(argv[1], "set", 3)) {
 -		if (argc < 5) 
-+		if (argc < 7) 
++		if (argc < 7)
  			return RESULT_SHOWUSAGE;
  
 -		if (ast_strlen_zero(argv[4]))
@@ -2281,22 +1919,24 @@
  
 + 		if (!argv[5])
 + 			return RESULT_SHOWUSAGE;
-+ 
++
 + 		if (!argv[6] || ast_strlen_zero(argv[6]))
 + 			return RESULT_SHOWUSAGE;
-+ 
++
 + 		span = atoi(argv[6]);
 + 		if ((span < 1) && (span > NUM_SPANS)) {
 + 			return RESULT_SUCCESS;
 + 		}
-+ 		
++
 +
  		myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
  		if (myfd < 0) {
  			ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
  			return RESULT_SUCCESS;
  		}
--
++ 		for (x=0; x < NUM_SPANS; x++) {
++ 	    	    ast_mutex_lock(&pris[x].lock);
+ 
 -		ast_mutex_lock(&pridebugfdlock);
 -
 -		if (pridebugfd >= 0)
@@ -2306,11 +1946,6 @@
 -		ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
 -		
 -		ast_mutex_unlock(&pridebugfdlock);
--
--		ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
-+ 		for (x=0; x < NUM_SPANS; x++) {
-+ 	    	    ast_mutex_lock(&pris[x].lock);
-+ 		    
 + 		    if (pris[x].span == span) {
 + 			if (pris[x].debugfd >= 0)
 + 			    close(pris[x].debugfd);
@@ -2322,7 +1957,8 @@
 + 		    }
 + 	    	    ast_mutex_unlock(&pris[x].lock);
 + 		}
-+  
+ 
+-		ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
 + 		ast_cli(fd, "PRI debug output for span %d will be sent to '%s'\n", span, argv[4]);
  	} else {
 + 		if (!argv[5] || ast_strlen_zero(argv[5]))
@@ -2337,10 +1973,10 @@
 + 		if ((span < 1) && (span > NUM_SPANS)) {
 + 			return RESULT_SUCCESS;
 + 		}
-+ 
++
 + 		for (x=0; x < NUM_SPANS; x++) {
 + 	    	    ast_mutex_lock(&pris[x].lock);
-+ 		    
++
 + 		    if (pris[x].span == span) {
 + 			if (pris[x].debugfd >= 0)
 + 			    close(pris[x].debugfd);
@@ -2352,12 +1988,12 @@
 + 		    }
 + 	    	    ast_mutex_unlock(&pris[x].lock);
 + 		}
-+ 
++
 + 		ast_cli(fd, "PRI debug output to file for span %d disabled\n", span);
  	}
  
  	return RESULT_SUCCESS;
-@@ -9692,6 +10697,7 @@ static int handle_pri_debug(int fd, int 
+@@ -9583,6 +10260,7 @@
  
  
  
@@ -2365,7 +2001,7 @@
  static int handle_pri_no_debug(int fd, int argc, char *argv[])
  {
  	int span;
-@@ -9841,10 +10847,6 @@ static int handle_pri_show_debug(int fd,
+@@ -9732,10 +10410,6 @@
  		}
  
  	}
@@ -2376,26 +2012,26 @@
  	    
  	if (!count) 
  		ast_cli(fd, "No debug set or no PRI running\n");
-@@ -9871,6 +10873,18 @@ static const char pri_show_spans_help[] 
+@@ -9762,6 +10436,18 @@
  	"Usage: pri show spans\n"
  	"       Displays PRI Information\n";
  
-+static char bri_debug_help[] = 
++static char bri_debug_help[] =
 +	"Usage: bri debug span <span>\n"
 +	"       Enables debugging on a given BRI span\n";
-+	
-+static char bri_no_debug_help[] = 
++
++static char bri_no_debug_help[] =
 +	"Usage: bri no debug span <span>\n"
 +	"       Disables debugging on a given BRI span\n";
 +
-+static char bri_really_debug_help[] = 
++static char bri_really_debug_help[] =
 +	"Usage: bri intensive debug span <span>\n"
 +	"       Enables debugging down to the Q.921 level\n";
 +
  static struct ast_cli_entry zap_pri_cli[] = {
  	{ { "pri", "debug", "span", NULL },
  	handle_pri_debug, "Enables PRI debugging on a span",
-@@ -9895,6 +10909,15 @@ static struct ast_cli_entry zap_pri_cli[
+@@ -9786,6 +10472,15 @@
  	{ { "pri", "show", "debug", NULL },
  	handle_pri_show_debug, "Displays current PRI debug settings" },
  
@@ -2411,7 +2047,7 @@
  	{ { "pri", "set", "debug", "file", NULL },
  	handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
  
-@@ -9902,8 +10925,76 @@ static struct ast_cli_entry zap_pri_cli[
+@@ -9793,8 +10488,76 @@
  	handle_pri_set_debug_file, "Ends PRI debug output to file" },
  };
  
@@ -2488,7 +2124,7 @@
  static int zap_destroy_channel(int fd, int argc, char **argv)
  {
  	int channel;
-@@ -10484,8 +11575,11 @@ static int __unload_module(void)
+@@ -10375,8 +11138,11 @@
  	}
  	ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
  	ast_unregister_application(zap_send_keypad_facility_app);
@@ -2500,7 +2136,7 @@
  	ast_manager_unregister( "ZapDialOffhook" );
  	ast_manager_unregister( "ZapHangup" );
  	ast_manager_unregister( "ZapTransfer" );
-@@ -10987,6 +12081,22 @@ static int process_zap(struct zt_chan_co
+@@ -10878,6 +11644,22 @@
  					confp->chan.sig = SIG_GR303FXSKS;
  					confp->chan.radio = 0;
  					confp->pri.nodetype = PRI_CPE;
@@ -2523,7 +2159,7 @@
  #endif
  				} else {
  					ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
-@@ -11099,9 +12209,21 @@ static int process_zap(struct zt_chan_co
+@@ -10990,9 +11772,21 @@
  					confp->chan.priindication_oob = 1;
  				else if (!strcasecmp(v->value, "inband"))
  					confp->chan.priindication_oob = 0;
@@ -2546,7 +2182,7 @@
  			} else if (!strcasecmp(v->name, "priexclusive")) {
  				confp->chan.priexclusive = ast_true(v->value);
  			} else if (!strcasecmp(v->name, "internationalprefix")) {
-@@ -11114,6 +12236,10 @@ static int process_zap(struct zt_chan_co
+@@ -11005,6 +11799,10 @@
  				ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
  			} else if (!strcasecmp(v->name, "unknownprefix")) {
  				ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
@@ -2557,7 +2193,7 @@
  			} else if (!strcasecmp(v->name, "resetinterval")) {
  				if (!strcasecmp(v->value, "never"))
  					confp->pri.resetinterval = -1;
-@@ -11130,6 +12256,8 @@ static int process_zap(struct zt_chan_co
+@@ -11021,6 +11819,8 @@
  				ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
  			} else if (!strcasecmp(v->name, "idledial")) {
  				ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
@@ -2566,7 +2202,7 @@
  			} else if (!strcasecmp(v->name, "overlapdial")) {
  				confp->pri.overlapdial = ast_true(v->value);
  			} else if (!strcasecmp(v->name, "pritimer")) {
-@@ -11431,6 +12559,7 @@ static int setup_zap(int reload)
+@@ -11322,6 +12122,7 @@
  #ifdef HAVE_PRI
  	if (!reload) {
  		for (x = 0; x < NUM_SPANS; x++) {
@@ -2574,7 +2210,7 @@
  			if (pris[x].pvts[0]) {
  				if (start_pri(pris + x)) {
  					ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
-@@ -11478,7 +12607,10 @@ static int load_module(void)
+@@ -11369,7 +12170,10 @@
  	ast_string_field_init(&inuse, 16);
  	ast_string_field_set(&inuse, name, "GR-303InUse");
  	ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
@@ -2585,7 +2221,7 @@
  	ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
  	
  	memset(round_robin, 0, sizeof(round_robin));
-@@ -11512,6 +12644,7 @@ static int zt_sendtext(struct ast_channe
+@@ -11403,6 +12207,7 @@
  	float scont = 0.0;
  	int index;
  
@@ -2593,9 +2229,11 @@
  	index = zt_get_index(c, p, 0);
  	if (index < 0) {
  		ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
---- a/configs/zapata.conf.sample
-+++ b/configs/zapata.conf.sample
-@@ -123,9 +123,20 @@ switchtype=national
+Index: asterisk-14/configs/zapata.conf.sample
+===================================================================
+--- asterisk-14.orig/configs/zapata.conf.sample	2008-01-20 21:55:17.000000000 +0200
++++ asterisk-14/configs/zapata.conf.sample	2008-01-20 21:56:58.000000000 +0200
+@@ -123,9 +123,20 @@
  ; 
  ; outofband:      Signal Busy/Congestion out of band with RELEASE/DISCONNECT
  ; inband:         Signal Busy/Congestion using in-band tones
@@ -2616,16 +2254,3 @@
  ; If you need to override the existing channels selection routine and force all
  ; PRI channels to be marked as exclusively selected, set this to yes.
  ; priexclusive = yes
---- a/main/channel.c
-+++ b/main/channel.c
-@@ -4209,6 +4209,10 @@ enum ast_bridge_result ast_channel_bridg
- 			c1->name, c1->_bridge->name);
- 		return -1;
- 	}
-+
-+	if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) {
-+	    config->flags = 0;
-+	}
- 	
- 	/* Stop if we're a zombie or need a soft hangup */
- 	if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||

Added: asterisk/trunk/debian/patches/bristuff/zapata_euroisdn_holded
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/trunk/debian/patches/bristuff/zapata_euroisdn_holded?rev=5162&op=file
==============================================================================
--- asterisk/trunk/debian/patches/bristuff/zapata_euroisdn_holded (added)
+++ asterisk/trunk/debian/patches/bristuff/zapata_euroisdn_holded Mon Jan 21 15:46:53 2008
@@ -1,0 +1,476 @@
+Index: asterisk-14/main/pbx.c
+===================================================================
+--- asterisk-14.orig/main/pbx.c	2008-01-21 12:12:16.000000000 +0200
++++ asterisk-14/main/pbx.c	2008-01-21 14:43:39.000000000 +0200
+@@ -5128,7 +5128,7 @@
+ };
+ 
+ /*! \brief run the application and free the descriptor once done */
+-static void *ast_pbx_run_app(void *data)
++void *ast_pbx_run_app(void *data)
+ {
+ 	struct app_tmp *tmp = data;
+ 	struct ast_app *app;
+Index: asterisk-14/include/asterisk/pbx.h
+===================================================================
+--- asterisk-14.orig/include/asterisk/pbx.h	2008-01-21 12:12:16.000000000 +0200
++++ asterisk-14/include/asterisk/pbx.h	2008-01-21 14:43:39.000000000 +0200
+@@ -145,6 +145,8 @@
+  */
+ struct ast_app *pbx_findapp(const char *app);
+ 
++void *ast_pbx_run_app(void *data);
++
+ /*!
+  * \brief Execute an application
+  *
+Index: asterisk-14/channels/chan_zap.c
+===================================================================
+--- asterisk-14.orig/channels/chan_zap.c	2008-01-21 12:26:22.000000000 +0200
++++ asterisk-14/channels/chan_zap.c	2008-01-21 14:54:48.000000000 +0200
+@@ -304,6 +304,19 @@
+ 	struct zt_suspended_call *next;
+ };
+ 
++struct zt_holded_call {
++	ast_mutex_t lock;		/* Mutex */
++	char msn[AST_MAX_EXTENSION];	/* the MSN to which this parked call belongs */
++	char uniqueid[AST_MAX_EXTENSION];	/* unique id of the onhold channel */
++	int tei;
++	int cref;
++	int alreadyhungup;
++	struct ast_channel *channel;
++	struct ast_channel *bridge;
++	q931_call *call;	/* this also covers tei mumbojumbo */
++	struct zt_holded_call *next;
++};
++
+ struct zt_pri {
+ 	pthread_t master;						/*!< Thread of master */
+ 	ast_mutex_t lock;						/*!< Mutex */
+@@ -347,6 +360,7 @@
+ 	struct zt_pvt *crvs;						/*!< Member CRV structs */
+ 	struct zt_pvt *crvend;						/*!< Pointer to end of CRV structs */
+  	struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */
++ 	struct zt_holded_call *holded_calls; /* Calls on hold */
+ 	int debugfd;
+ };
+ 
+@@ -7463,6 +7477,7 @@
+ 						pris[span].overlapdial = conf.pri.overlapdial;
+ 						pris[span].usercid = conf.pri.usercid;
+ 						pris[span].suspended_calls = NULL;
++						pris[span].holded_calls = NULL;
+ 						pris[span].facilityenable = conf.pri.facilityenable;
+ 						ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
+ 						ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
+@@ -8138,6 +8153,58 @@
+ 	return NULL;
+ }
+ 
++static int pri_find_tei(struct zt_pri *pri, q931_call *c, int tei)
++{
++	int x=0;
++	for (x=0;x<pri->numchans;x++) {
++		if (!pri->pvts[x]) continue;
++		if ((pri->pvts[x]->tei == tei) && (pri->pvts[x]-> call != c)) {
++		    return x;
++		}
++	}
++	return -1;
++}
++
++static struct zt_holded_call *pri_get_callonhold(struct zt_pri *pri, int cref, int tei) {
++	struct zt_holded_call *zhc = pri->holded_calls;
++	struct zt_holded_call *zhctemp = NULL;
++
++	while (zhc) {
++	    if ((zhc->tei == tei) && ((zhc->cref == cref) || (cref == -1))) {
++		return zhc;
++	    }
++	    zhctemp = zhc;
++	    if (zhc) zhc = zhc->next;
++	}
++	return NULL;
++}
++
++static int pri_destroy_callonhold(struct zt_pri *pri, struct zt_holded_call *onhold) {
++	struct zt_holded_call *zhc = pri->holded_calls;
++	struct zt_holded_call *zhctemp = NULL;
++
++	while (zhc) {
++	    if (zhc == onhold) {
++		if (zhctemp) {
++		    zhctemp->next = zhc->next;
++		    zhc = zhctemp;
++		} else {
++		    pri->holded_calls = zhc->next;
++		    zhc = pri->holded_calls;
++		    zhctemp = NULL;
++		}
++	    }
++	    zhctemp = zhc;
++	    if (zhc) zhc = zhc->next;
++	}
++	if (onhold) {
++	    free(onhold);
++	    onhold = NULL;
++	    return 1;
++	}
++	return 0;
++}
++
+ 
+ static int pri_find_principle(struct zt_pri *pri, int channel)
+ {
+@@ -9582,18 +9649,150 @@
+ 				    pri_hold_reject(pri->pri, e->hold_req.call);
+ 				    break;
+ 				}
+-				/* holded calls are not implemented yet */
+-				pri_hold_reject(pri->pri, e->hold_req.call);
++				chanpos = pri_find_principle(pri, e->hold_req.channel);
++				if (chanpos < 0)  {
++					ast_log(LOG_WARNING, "Hold requested on unconfigured channel %d span %d\n", chanpos, pri->span);
++					chanpos = -1;
++				}
++				if (chanpos > -1) {
++				//    ast_log(LOG_NOTICE, "Hold request for channel number %d span %d\n", chanpos, pri->span);
++				    ast_mutex_lock(&pri->pvts[chanpos]->lock);
++ 				    if (pri->pvts[chanpos]->owner) {
++					struct zt_pvt *p = pri->pvts[chanpos];
++					struct zt_holded_call *zhc;
++					int holdacked=0;
++
++//					ast_log(LOG_NOTICE,"HOLD request from channel %s tei %d\n",p->owner->name, e->hold_req.tei);
++				    	if (ast_bridged_channel(p->owner)) {
++					    zhc = malloc(sizeof(struct zt_holded_call));
++					    if (!zhc) {
++						ast_log(LOG_ERROR, "unable to malloc zt_holded_call\n");
++						break;
++					    }
++					    memset(zhc, 0, sizeof(zhc));
++					    strncpy(zhc->msn,  pri->pvts[chanpos]->cid_num, sizeof(zhc->msn));
++					    strncpy(zhc->uniqueid,  ast_bridged_channel(p->owner)->uniqueid, sizeof(zhc->uniqueid));
++					    zhc->tei = e->hold_req.tei;
++					    zhc->cref = e->hold_req.cref;
++					    zhc->call = e->hold_req.call;
++					    zhc->channel = p->owner;
++					    zhc->alreadyhungup = 0;
++					    zhc->bridge = ast_bridged_channel(p->owner);
++					    zhc->next = pri->holded_calls;
++					    pri->holded_calls = zhc;
++
++					    /* put channel on hold */
++					    ast_masq_hold_call(ast_bridged_channel(p->owner), p->owner);
++
++					    pri_hold_acknowledge(pri->pri, e->hold_req.call);
++					    holdacked = 1;
++					    p->call = NULL; // free the bchannel withouth destroying the call
++					    p->tei = -1;
++					} else {
++					    // cant hold a non-bridge,...yet
++
++					    // make a fake channel
++
++					    // masquerade
++
++					    // put on hold
++					    pri_hold_reject(pri->pri, e->hold_req.call);
++					}
++				    } else {
++					    pri_hold_reject(pri->pri, e->hold_req.call);
++				    }
++				    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
++				} else {
++					pri_hold_reject(pri->pri, e->hold_req.call);
++				}
+ 				break;
+ 			case PRI_EVENT_RETRIEVE_REQ:
+ 				if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
+ 				    pri_retrieve_reject(pri->pri, e->retrieve_req.call);
+ 				    break;
+ 				}
+-				/* Holded calls are currently not supported */
+-				pri_retrieve_reject(pri->pri, e->retrieve_req.call);
+-				chanpos = -1;
+-				break;
++				chanpos = pri_find_empty_chan(pri, 1);
++				if (chanpos < 0) {
++					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
++					ast_log(LOG_WARNING, "Retrieve requested on odd channel number %d span %d\n", chanpos, pri->span);
++					chanpos = -1;
++					break;
++				} else if (!pri->pvts[chanpos]) {
++					ast_log(LOG_WARNING, "Retrieve requested on unconfigured channel number %d span %d\n", chanpos, pri->span);
++					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
++					chanpos = -1;
++					break;
++				}
++				if (chanpos > -1) {
++				    struct zt_holded_call *onhold = NULL;
++				    int retrieved = 0;
++				    int res = -1;
++				    struct app_tmp *tmp;
++				    pthread_attr_t attr;
++				    int law;
++
++				    onhold = pri_get_callonhold(pri, e->retrieve_req.cref, e->retrieve_req.tei);
++
++				    if (!onhold) {
++					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
++					break;
++				    }
++				    ast_mutex_lock(&pri->pvts[chanpos]->lock);
++					// found a parked call
++ 					law = 1;
++					if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
++					    ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law);
++					// uhh ohh...what shall we do without the bearer cap???
++					law = ZT_LAW_ALAW;
++					res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
++					if (res < 0)
++					    ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
++					res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
++					if (res < 0)
++					    ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
++					/* Start PBX */
++					c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 0, SUB_REAL, law, PRI_TRANS_CAP_SPEECH);
++					if (c) {
++					    pri->pvts[chanpos]->owner = c;
++					    pri->pvts[chanpos]->outgoing = 1; /* for not sending proceedings... */
++					    pri->pvts[chanpos]->call = e->retrieve_req.call;
++					    pri->pvts[chanpos]->tei = e->retrieve_req.tei;
++				    	    zt_enable_ec(pri->pvts[chanpos]);
++				    	    zt_train_ec(pri->pvts[chanpos]);
++					} else {
++					    ast_log(LOG_ERROR, "unable to start pbx\n");
++					}
++
++					retrieved = 1;
++				//	ast_log(LOG_NOTICE, "sending RETRIEVE ACK on channel %d, span %d for tei %d cref %d\n",chanpos,pri->span, e->retrieve_req.tei,  e->retrieve_req.cref);
++					pri_retrieve_acknowledge(pri->pri, e->retrieve_req.call, chanpos + 1);
++
++					// the magic begins here: ....
++					tmp = malloc(sizeof(struct app_tmp));
++					if (tmp) {
++					    memset(tmp, 0, sizeof(struct app_tmp));
++					    strncpy(tmp->app, "holdedcall", sizeof(tmp->app) - 1);
++					    strncpy(tmp->data, onhold->uniqueid, sizeof(tmp->data) - 1);
++					    tmp->chan = c;
++					}
++					pri_destroy_callonhold(pri, onhold);
++					onhold = NULL;
++
++					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
++					pthread_attr_init(&attr);
++					pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
++					if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
++ 					    ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", c->name, strerror(errno));
++					    free(tmp);
++					    ast_hangup(c);
++					    retrieved = 0;
++					}
++
++				    if (!retrieved) {
++					pri_retrieve_reject(pri->pri, e->retrieve_req.call);
++				    }
++				}
++ 				break;
+ 			case PRI_EVENT_DISPLAY_RECEIVED:
+ 				ast_log(LOG_NOTICE, "DISPLAY IE: [ %s ] received\n",e->display.text);
+ 				chanpos = pri_find_principle(pri, e->display.channel);
+@@ -9750,9 +9949,20 @@
+ 
+ 						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
+ 					} else {
+-						ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
+-						ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
+-								PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
++ 						struct zt_holded_call *onhold = NULL;
++						/* check calls on hold */
++ 						onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei);
++
++ 						if (onhold) {
++ 						    // ast_log(LOG_NOTICE, "hangup, found cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
++ 						    pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1);
++ 						    pri_destroy_callonhold(pri, onhold);
++ 						    onhold = NULL;
++ 						} else {
++ 						    ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
++ 						    ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
++  							PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
++ 						}
+ 					}
+ 				} 
+ 				break;
+@@ -9815,11 +10025,63 @@
+ 							    	ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
+ 									pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
+ 							}
+-							if (pri->nodetype == BRI_NETWORK_PTMP) {
+-								pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
+-								pri->pvts[chanpos]->call = NULL;
+-								pri->pvts[chanpos]->tei = -1;
+-							}
++ 							if (pri->nodetype == BRI_NETWORK_PTMP) {
++							    // check for bri transfers, not everybody uses ECT...
++ 							    if (pri->pvts[chanpos]->owner) {
++ 								// find on hold call
++								struct zt_holded_call *onhold = NULL;
++ 								struct ast_channel *transferee = NULL;
++								int transfer_ok = 0;
++
++ 								onhold = pri_get_callonhold(pri, -1, e->hangup.tei);
++
++ 								if (onhold) {
++								    if (pri->pvts[chanpos]->pritransfer == 2) {
++ 									if (((pri->pvts[chanpos]->owner->_state != AST_STATE_RING) && (pri->pvts[chanpos]->owner->_state != AST_STATE_RESERVED)) || ((!ast_strlen_zero(pri->pvts[chanpos]->exten)) && (strncasecmp(pri->pvts[chanpos]->exten, "s", sizeof(pri->pvts[chanpos]->exten))))) {
++ 								    	    transferee = ast_get_holded_call(onhold->uniqueid);
++
++ 									    if (transferee) {
++ 										if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) {
++ 									    	    ast_indicate(transferee, AST_CONTROL_RINGING);
++ 										}
++
++ 										pri->pvts[chanpos]->owner->_softhangup &= ~AST_SOFTHANGUP_DEV;
++
++  									        ast_mutex_unlock(&transferee->lock);
++ 										if (ast_channel_masquerade(pri->pvts[chanpos]->owner, transferee)) {
++ 										    ast_log(LOG_WARNING, "unable to masquerade\n");
++ 									        } else {
++ 									    	    /* beware of zombies!!! */
++										    ast_set_flag(transferee, AST_FLAG_ZOMBIE);
++ 										    pri->pvts[chanpos]->owner = NULL;
++ 										    pri->pvts[chanpos]->tei = -1;
++										    transfer_ok = 1;
++ 										}
++ 									    }
++									}
++ 								    } else if (pri->pvts[chanpos]->pritransfer == 0) {
++									ast_log(LOG_NOTICE, "killing channel %s \n", onhold->uniqueid);
++ 									ast_retrieve_call_to_death(onhold->uniqueid);
++									transfer_ok = 1;
++ 								    } else if (pri->pvts[chanpos]->pritransfer == 1) {
++									/* we use ECT transfers, so just ignore this */
++									transfer_ok = 0;
++								    }
++
++								    if (transfer_ok) {
++ 									onhold->alreadyhungup = 1;
++ 									pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1);
++ 									onhold = NULL;
++								    }
++ 								    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
++ 								    break;
++                                                        	} else {
++                                                                    pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
++                                                                        pri->pvts[chanpos]->call = NULL;
++                                                                        pri->pvts[chanpos]->tei = -1;
++                                                                }
++  							    }
++  							}
+ 						} else {
+ 							pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
+ 							pri->pvts[chanpos]->call = NULL;
+@@ -9849,7 +10111,19 @@
+  						if (pri->nodetype != BRI_NETWORK_PTMP) {
+   						    ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+  						} else {
+-							ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
++ 						    // check holded_calls!!!
++ 						    struct zt_holded_call *onhold = NULL;
++
++ 						    onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei);
++
++ 						    if (onhold) {
++ 							    pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1);
++ 							    ast_retrieve_call_to_death(onhold->uniqueid);
++ 							    pri_destroy_callonhold(pri, onhold);
++ 							    onhold = NULL;
++ 						    } else {
++ 							ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
++ 						    }
+  						}
+ 					}
+ 				} 
+@@ -10011,16 +10285,73 @@
+ 				}
+ 				break;
+  			case PRI_EVENT_FACILITY:
+- 				    if (e->facility.operation == 0x0D) {
+-				    	struct ast_channel *owner = pri->pvts[chanpos]->owner;
++ 				    if (e->facility.operation == 0x06) {
++ 					struct ast_channel *chan = NULL;
++ 					struct zt_holded_call *onhold = NULL;
++ 					if (option_verbose > 2) {
++ 					    ast_verbose(VERBOSE_PREFIX_3 "ECT requested by TEI %d for cref %d\n", e->facility.tei, e->facility.cref);
++ 					}
++ 					/* search for cref/tei in held calls */
++ 					onhold = pri_get_callonhold(pri, e->facility.cref, e->facility.tei);
++ 					if (onhold) {
++ 					    chan = ast_get_holded_call(onhold->uniqueid);
++ 					    onhold->alreadyhungup = 1;
++ 					    onhold = NULL;
++ 					    if (!chan) {
++ 						/* hang up */
++ 					        pri_hangup(pri->pri, e->facility.call, 16, -1);
++ 						break;
++ 					    }
++ 					} else {
++ 					    /* unknown cref/tei */
++ 					    ast_log(LOG_WARNING, "did not find call on hold for cref %d tei %d\n", e->facility.tei, e->facility.cref);
++ 					    /* hang up */
++ 					    pri_hangup(pri->pri, e->facility.call, 16, -1);
++ 					    break;
++ 					}
+ 
++ 					/* find an active call for the same tei */
++ 					chanpos = pri_find_tei(pri, e->facility.call, e->facility.tei);
++ 					if (chanpos < 0) {
++ 					    /* did not find active call, hangup call on hold */
++ 					    if (chan) {
++ 						ast_hangup(chan);
++ 						chan = NULL;
++ 					    }
++ 					} else {
++ 					    ast_mutex_lock(&pri->pvts[chanpos]->lock);
++ 					    /* transfer */
++ 					    if (pri->pvts[chanpos]->owner) {
++ 						if (option_verbose > 3) {
++ 						    ast_verbose(VERBOSE_PREFIX_3 "ECT: found %s on channel %d for tei %d\n", pri->pvts[chanpos]->owner->name ,chanpos, e->facility.tei);
++ 						}
++ 						/* pass callprogress if the channel is not up yet */
++ 						if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) {
++ 						    ast_indicate(chan, AST_CONTROL_RINGING);
++ 						}
++ 						/* unlock the channel we removed from hold */
++ 						ast_mutex_unlock(&chan->lock);
++ 						if (ast_channel_masquerade(pri->pvts[chanpos]->owner, chan)) {
++ 					    	    ast_log(LOG_WARNING, "unable to masquerade\n");
++ 						} else {
++ 						    /* beware of zombies !!! */
++						    ast_set_flag(chan, AST_FLAG_ZOMBIE);
++ 						//    chan->zombie = 1;
++ 						}
++ 					    }
++ 					    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
++ 					}
++					/* disconnect */
++ 					pri_hangup(pri->pri, e->facility.call, 16, -1);
++ 				    } else if (e->facility.operation == 0x0D) {
+  					ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum);
+  					ast_mutex_lock(&pri->pvts[chanpos]->lock);
+  					    /* transfer */
+- 					    if (owner) {
+-						ast_string_field_build(owner, call_forward, 
+-								"Local/%s@%s",  e->facility.forwardnum,
+-								owner->context);
++ 					    if (pri->pvts[chanpos]->owner) {
++					    	struct ast_channel *owner = pri->pvts[chanpos]->owner;
++							ast_string_field_build(owner, call_forward,
++									"Local/%s@%s", e->facility.forwardnum,
++									owner->context);
+  					    }
+  					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
+  				    } else {

Added: asterisk/trunk/debian/patches/bristuff/zapata_num_spans
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/trunk/debian/patches/bristuff/zapata_num_spans?rev=5162&op=file
==============================================================================
--- asterisk/trunk/debian/patches/bristuff/zapata_num_spans (added)
+++ asterisk/trunk/debian/patches/bristuff/zapata_num_spans Mon Jan 21 15:46:53 2008
@@ -1,0 +1,18 @@
+# Allow as many spans as Zaptel can take (defualt: 128).
+# There is a static array of zt_pris allocated at this size.
+# For that reason upstream only sort-of merged it: made it a
+# compile-time option in 1.6 .
+
+Index: asterisk-1.4.17/channels/chan_zap.c
+===================================================================
+--- asterisk-1.4.17.orig/channels/chan_zap.c
++++ asterisk-1.4.17/channels/chan_zap.c
+@@ -190,7 +194,7 @@ static const char config[] = "zapata.con
+ #define SIG_GR303FXOKS	(0x0100000 | ZT_SIG_FXOKS)
+ #define SIG_GR303FXSKS	(0x0100000 | ZT_SIG_FXSKS)
+ 
+-#define NUM_SPANS 		32
++#define NUM_SPANS 		ZT_MAX_SPANS
+ #define NUM_DCHANS		4	/*!< No more than 4 d-channels */
+ #define MAX_CHANNELS	672		/*!< No more than a DS3 per trunk group */
+ 

Modified: asterisk/trunk/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/trunk/debian/patches/series?rev=5162&op=diff
==============================================================================
--- asterisk/trunk/debian/patches/series (original)
+++ asterisk/trunk/debian/patches/series Mon Jan 21 15:46:53 2008
@@ -2,7 +2,6 @@
 debian-banner
 silence-buildsum-warning
 configure-libc-client
-hack-multiple-app-voicemail
 astvarrundir
 make-clean-fixes
 safe_asterisk-config
@@ -47,8 +46,11 @@
 bristuff/app-dial-R-noinband
 bristuff/app-dial-c-callback
 
-# improved (?) devicestate support in chan_zap. Not used:
-bristuff/zapata-device-state
+bristuff/zapata_num_spans
+
+# use /usr/include/bristuffed/libpri.h - /usr/lib/libpri-bristuffed.so.1.0
+use-libpri-bristuffed
+bristuff/zapata-bri+euroisdn
 
 # and here goes our API :-)
 bristuff/ast-send-message
@@ -67,7 +69,7 @@
 # they depend on the uniqueid changes; the following are a set
 bristuff/feature-autoanswer
 bristuff/feature-holdedcalls
-bristuff/zapata-bri+euroisdn
+bristuff/zapata_euroisdn_holded
 # GSM support; it needs the above patch applied first, unfortunately.
 bristuff/zapata-gsm
 
@@ -79,5 +81,3 @@
 #bristuff/find-feature
 #bristuff/feature-parking_con
 
-# use /usr/include/bristuffed/libpri.h - /usr/lib/libpri-bristuffed.so.1.0
-use-libpri-bristuffed




More information about the Pkg-voip-commits mailing list