[Pkg-voip-commits] r3859 - in libpri/trunk/debian: . patches

tzafrir-guest at alioth.debian.org tzafrir-guest at alioth.debian.org
Sat Jul 28 08:17:26 UTC 2007


Author: tzafrir-guest
Date: 2007-07-28 08:17:25 +0000 (Sat, 28 Jul 2007)
New Revision: 3859

Modified:
   libpri/trunk/debian/changelog
   libpri/trunk/debian/patches/00list
   libpri/trunk/debian/patches/bristuff.dpatch
   libpri/trunk/debian/patches/libname.dpatch
   libpri/trunk/debian/rules
Log:
* Re-Adding bristuff.
* Which requires re-applying and fixing libname.dpatch .


Modified: libpri/trunk/debian/changelog
===================================================================
--- libpri/trunk/debian/changelog	2007-07-27 19:04:49 UTC (rev 3858)
+++ libpri/trunk/debian/changelog	2007-07-28 08:17:25 UTC (rev 3859)
@@ -7,13 +7,17 @@
   * Revert to libpri1 to comply with SONAME
 
   [ Faidon Liambotis ]
-  * Add myself to Uploaders. 
+  * Add myself to Uploaders.
   * Add XS-Vcs-Svn and XS-Vcs-Browser to debian/control.
   * Switch to dh_install from the deprecated dh_movefiles.
   * Use ${binary:Version} instead of ${Source-Version}.
 
- -- Faidon Liambotis <paravoid at debian.org>  Sun, 22 Jul 2007 08:49:05 +0300
+  [ Tzafrir Cohen ]
+  * Re-Adding bristuff.
+  * Which requires re-applying and fixing libname.dpatch .
 
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Fri, 27 Jul 2007 23:34:10 +0300
+
 libpri (1.4.0-2) unstable; urgency=low
 
   * unstable release

Modified: libpri/trunk/debian/patches/00list
===================================================================
--- libpri/trunk/debian/patches/00list	2007-07-27 19:04:49 UTC (rev 3858)
+++ libpri/trunk/debian/patches/00list	2007-07-28 08:17:25 UTC (rev 3859)
@@ -1 +1 @@
-#libname
+libname

Modified: libpri/trunk/debian/patches/bristuff.dpatch
===================================================================
--- libpri/trunk/debian/patches/bristuff.dpatch	2007-07-27 19:04:49 UTC (rev 3858)
+++ libpri/trunk/debian/patches/bristuff.dpatch	2007-07-28 08:17:25 UTC (rev 3859)
@@ -2,7 +2,7 @@
 ## bristuff.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: The libpri part of bristuff, version bristuff-0.3.0-PRE-1v
+## DP: The libpri part of bristuff, version bristuff-0.4.0-test4
 ## DP: http://www.junghanns.net/en/download.html
 ## DP:
 ## DP: newer versions: replace the contets of the patch file literally.
@@ -10,9 +10,9 @@
 ## DP: copyright statements.
 
 @DPATCH@
-diff -urN libpri-1.2.4.orig/libpri.h libpri-1.2.4/libpri.h
---- libpri-1.2.4.orig/libpri.h	2006-04-27 18:08:39.000000000 +0200
-+++ libpri-1.2.4/libpri.h	2006-07-11 11:34:59.000000000 +0200
+diff -urN libpri-1.4.1.orig/libpri.h libpri-1.4.1/libpri.h
+--- libpri-1.4.1.orig/libpri.h	2006-04-27 18:09:11.000000000 +0200
++++ libpri-1.4.1/libpri.h	2007-07-11 14:25:15.000000000 +0200
 @@ -5,6 +5,8 @@
   *
   * Copyright (C) 2001, Linux Support Services, Inc.
@@ -49,7 +49,7 @@
  
  /* Simple states */
  #define PRI_STATE_DOWN		0
-@@ -250,11 +262,17 @@
+@@ -252,11 +264,17 @@
  #define PRI_NSF_ATT_MULTIQUEST         0xF0
  #define PRI_NSF_CALL_REDIRECTION_SERVICE       0xF7
  
@@ -67,7 +67,7 @@
  } pri_event_generic;
  
  typedef struct pri_event_error {
-@@ -273,18 +291,19 @@
+@@ -275,18 +293,19 @@
  	int cref;
  	int progress;
  	int progressmask;
@@ -89,7 +89,7 @@
  } pri_event_answer;
  
  typedef struct pri_event_facname {
-@@ -302,32 +321,37 @@
+@@ -304,32 +323,37 @@
  	int e;
  	int channel;				/* Channel requested */
  	int callingpres;			/* Presentation of Calling CallerID */
@@ -136,7 +136,7 @@
  } pri_event_ring;
  
  typedef struct pri_event_hangup {
-@@ -335,6 +359,8 @@
+@@ -337,6 +361,8 @@
  	int channel;				/* Channel requested */
  	int cause;
  	int cref;
@@ -145,7 +145,7 @@
  	q931_call *call;			/* Opaque call pointer */
  	long aoc_units;				/* Advise of Charge number of charged units */
  	char useruserinfo[260];		/* User->User info */
-@@ -375,20 +401,80 @@
+@@ -377,20 +403,80 @@
  	char digits[64];
  } pri_event_keypad_digit;
  
@@ -227,7 +227,7 @@
  	pri_event_keypad_digit digit;			/* Digits that come during a call */
  } pri_event;
  
-@@ -403,7 +489,9 @@
+@@ -405,7 +491,9 @@
     channel operating in HDLC mode with FCS computed by the fd's driver.  Also it
     must be NON-BLOCKING! Frames received on the fd should include FCS.  Nodetype 
     must be one of PRI_NETWORK or PRI_CPE.  switchtype should be PRI_SWITCH_* */
@@ -238,7 +238,7 @@
  
  /* Create D-channel just as above with user defined I/O callbacks and data */
  extern struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata);
-@@ -427,6 +515,9 @@
+@@ -429,6 +517,9 @@
  /* Enable transmission support of Facility IEs on the pri */
  extern void pri_facility_enable(struct pri *pri);
  
@@ -248,9 +248,9 @@
  /* Run PRI on the given D-channel, taking care of any events that
     need to be handled.  If block is set, it will block until an event
     occurs which needs to be handled */
-@@ -463,6 +554,12 @@
- /* Send a digit in overlap mode */
- extern int pri_information(struct pri *pri, q931_call *call, char digit);
+@@ -469,6 +560,12 @@
+ /* Send a keypad facility string of digits */
+ extern int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits);
  
 +/* Send a INFO msg with display ie  */
 +extern int pri_information_display(struct pri *pri, q931_call *call, char *display);
@@ -261,7 +261,7 @@
  /* Answer the incomplete(call without called number) call on the given channel.
     Set non-isdn to non-zero if you are not connecting to ISDN equipment */
  extern int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
-@@ -471,6 +568,35 @@
+@@ -477,6 +574,35 @@
     Set non-isdn to non-zero if you are not connecting to ISDN equipment */
  extern int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
  
@@ -297,7 +297,7 @@
  /* Set CRV reference for GR-303 calls */
  
  
-@@ -479,14 +605,14 @@
+@@ -485,14 +611,14 @@
  
  /* backwards compatibility for those who don't use asterisk with libpri */
  #define pri_release(a,b,c) \
@@ -315,7 +315,7 @@
  
  #define PRI_DESTROYCALL
  extern void pri_destroycall(struct pri *pri, q931_call *call);
-@@ -519,14 +645,13 @@
+@@ -525,7 +651,7 @@
  extern void pri_sr_free(struct pri_sr *sr);
  
  extern int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
@@ -324,15 +324,8 @@
  extern int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
  extern int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
  extern int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
- #define PRI_USER_USER_TX
- /* Set the user user field.  Warning!  don't send binary data accross this field */
- extern void pri_sr_set_useruser(struct pri_sr *sr, char *userchars);
--
- extern void pri_call_set_useruser(q931_call *sr, char *userchars);
+@@ -553,8 +679,8 @@
  
- extern int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
-@@ -547,8 +672,8 @@
- 
  /* Override message and error stuff */
  #define PRI_NEW_SET_API
 -extern void pri_set_message(void (*__pri_error)(struct pri *pri, char *));
@@ -342,10 +335,10 @@
  
  /* Set overlap mode */
  #define PRI_SET_OVERLAPDIAL
-diff -urN libpri-1.2.4.orig/Makefile libpri-1.2.4/Makefile
---- libpri-1.2.4.orig/Makefile	2006-04-30 17:17:47.000000000 +0200
-+++ libpri-1.2.4/Makefile	2006-07-27 17:45:09.000000000 +0200
-@@ -27,6 +27,13 @@
+diff -urN libpri-1.4.1.orig/Makefile libpri-1.4.1/Makefile
+--- libpri-1.4.1.orig/Makefile	2006-12-30 20:17:34.000000000 +0100
++++ libpri-1.4.1/Makefile	2007-07-11 14:25:15.000000000 +0200
+@@ -27,6 +27,16 @@
  # Uncomment if you want libpri to count number of Q921/Q931 sent/received
  #LIBPRI_COUNTERS=-DLIBPRI_COUNTERS
  
@@ -356,21 +349,24 @@
 +# device sends a RELEASE COMPLETE with cause 17
 +#FASTBUSYONBUSY=-DFASTBUSYONBUSY
 +
++# workaround for slowly responding COs
++#RELAXEDTIMERS=-DRELAXED_TIMERS
++
  CC=gcc
  
  OSARCH=$(shell uname -s)
-@@ -38,7 +45,7 @@
+@@ -36,7 +46,7 @@
  DYNAMIC_LIBRARY=libpri.so.1.0
  STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o
  DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo
 -CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS)
-+CFLAGS=-Wall -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS) $(LAYER2ALWAYSUP) $(FASTBUSYONBUSY) -DRELAX_TRB
++CFLAGS=-Wall -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS) $(LAYER2ALWAYSUP) $(FASTBUSYONBUSY) -DRELAX_TRB $(RELAXEDTIMERS)
  INSTALL_PREFIX=$(DESTDIR)
  INSTALL_BASE=/usr
  SOFLAGS = -Wl,-hlibpri.so.1.0
-diff -urN libpri-1.2.4.orig/pri.c libpri-1.2.4/pri.c
---- libpri-1.2.4.orig/pri.c	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pri.c	2006-07-11 12:39:20.000000000 +0200
+diff -urN libpri-1.4.1.orig/pri.c libpri-1.4.1/pri.c
+--- libpri-1.4.1.orig/pri.c	2006-07-06 23:11:37.000000000 +0200
++++ libpri-1.4.1/pri.c	2007-07-11 14:25:15.000000000 +0200
 @@ -1,24 +1,14 @@
  /*
   * libpri: An implementation of Primary Rate ISDN
@@ -508,7 +504,7 @@
  int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
  {
  	if (!pri || !call)
-@@ -478,6 +488,21 @@
+@@ -486,6 +496,21 @@
  	return q931_notify(pri, call, channel, info);
  }
  
@@ -530,7 +526,7 @@
  void pri_destroycall(struct pri *pri, q931_call *call)
  {
  	if (pri && call)
-@@ -499,6 +524,76 @@
+@@ -507,6 +532,83 @@
  	return q931_connect(pri, call, channel, nonisdn);
  }
  
@@ -600,15 +596,22 @@
 +
 +int pri_deflect(struct pri *pri, q931_call *call, char *destination)
 +{
-+    add_call_deflection_facility_ie(pri, call, destination);
-+    return q931_facility(pri, call);
++    if ((pri->localtype == PRI_CPE) || (pri->localtype == BRI_CPE)) {
++	add_call_rerouting_facility_ie(pri, call, destination);
++	return q931_facility(pri, call);
++    } else if (pri->localtype == BRI_CPE_PTMP) {
++	add_call_deflection_facility_ie(pri, call, destination);
++	return q931_facility(pri, call);
++    } else {
++	return -1;
++    }
 +}
 +
  #if 0
  /* deprecated routines, use pri_hangup */
  int pri_release(struct pri *pri, q931_call *call, int cause)
-@@ -541,14 +636,35 @@
- 	return 0;
+@@ -547,14 +649,35 @@
+ 	return -1;
  }
  
 -int pri_hangup(struct pri *pri, q931_call *call, int cause)
@@ -645,7 +648,7 @@
  }
  
  int pri_reset(struct pri *pri, int channel)
-@@ -688,15 +804,15 @@
+@@ -694,15 +817,15 @@
  	return q931_setup(pri, c, &req);
  }	
  
@@ -665,7 +668,7 @@
  {
  	__pri_error = func;
  }
-@@ -708,10 +824,14 @@
+@@ -714,10 +837,14 @@
  	va_start(ap, fmt);
  	vsnprintf(tmp, sizeof(tmp), fmt, ap);
  	va_end(ap);
@@ -684,7 +687,7 @@
  }
  
  void pri_error(struct pri *pri, char *fmt, ...)
-@@ -721,10 +841,14 @@
+@@ -727,10 +854,14 @@
  	va_start(ap, fmt);
  	vsnprintf(tmp, sizeof(tmp), fmt, ap);
  	va_end(ap);
@@ -703,7 +706,7 @@
  }
  
  /* Set overlap mode */
-@@ -765,11 +889,13 @@
+@@ -771,11 +902,13 @@
  	}
  	len += sprintf(buf + len, "Q921 Outstanding: %d\n", q921outstanding);
  #endif
@@ -722,7 +725,7 @@
  	len += sprintf(buf + len, "Overlap Dial: %d\n", pri->overlapdial);
  	len += sprintf(buf + len, "T200 Timer: %d\n", pri->timers[PRI_TIMER_T200]);
  	len += sprintf(buf + len, "T203 Timer: %d\n", pri->timers[PRI_TIMER_T203]);
-@@ -778,6 +904,7 @@
+@@ -785,6 +918,7 @@
  	len += sprintf(buf + len, "T313 Timer: %d\n", pri->timers[PRI_TIMER_T313]);
  	len += sprintf(buf + len, "N200 Counter: %d\n", pri->timers[PRI_TIMER_N200]);
  
@@ -730,7 +733,7 @@
  	return strdup(buf);
  }
  
-@@ -819,10 +946,11 @@
+@@ -826,10 +960,11 @@
  	return 0;
  }
  
@@ -743,7 +746,7 @@
  	return 0;
  }
  
-@@ -851,3 +979,14 @@
+@@ -858,3 +993,14 @@
  	sr->redirectingreason = reason;
  	return 0;
  }
@@ -758,9 +761,9 @@
 +#endif
 +#endif
 +}
-diff -urN libpri-1.2.4.orig/pridump.c libpri-1.2.4/pridump.c
---- libpri-1.2.4.orig/pridump.c	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pridump.c	2006-01-18 12:28:07.000000000 +0100
+diff -urN libpri-1.4.1.orig/pridump.c libpri-1.4.1/pridump.c
+--- libpri-1.4.1.orig/pridump.c	2006-07-05 18:17:05.000000000 +0200
++++ libpri-1.4.1/pridump.c	2007-07-11 14:25:15.000000000 +0200
 @@ -1,9 +1,9 @@
  /*
   * libpri: An implementation of Primary Rate ISDN
@@ -773,9 +776,9 @@
   * All Rights Reserved.
   *
   * This program is free software; you can redistribute it and/or modify
-diff -urN libpri-1.2.4.orig/pri_facility.c libpri-1.2.4/pri_facility.c
---- libpri-1.2.4.orig/pri_facility.c	2006-02-14 00:06:02.000000000 +0100
-+++ libpri-1.2.4/pri_facility.c	2006-06-06 14:26:01.000000000 +0200
+diff -urN libpri-1.4.1.orig/pri_facility.c libpri-1.4.1/pri_facility.c
+--- libpri-1.4.1.orig/pri_facility.c	2007-06-06 23:58:22.000000000 +0200
++++ libpri-1.4.1/pri_facility.c	2007-07-11 14:25:15.000000000 +0200
 @@ -1,26 +1,17 @@
 -/*
 - * libpri: An implementation of Primary Rate ISDN
@@ -817,7 +820,7 @@
  
  #include "compat.h"
  #include "libpri.h"
-@@ -208,9 +199,9 @@
+@@ -350,9 +341,9 @@
  	if (datalen > buflen) {
  		/* Truncate */
  		datalen = buflen;
@@ -829,7 +832,7 @@
  }
  
  int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len)
-@@ -305,12 +296,55 @@
+@@ -447,12 +438,55 @@
  			return -1;
  		value->ton = ton;
  
@@ -886,7 +889,7 @@
  static int rose_address_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
  {
  	int i = 0;
-@@ -375,11 +409,10 @@
+@@ -517,11 +551,10 @@
  			pri_message(pri, "!! Unknown Party number component received 0x%X\n", comp->type);
  			return -1;
  		}
@@ -899,7 +902,7 @@
  	}
  	while (0);
  
-@@ -389,7 +422,6 @@
+@@ -531,7 +564,6 @@
  static int rose_presented_number_unscreened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
  {
  	int i = 0;
@@ -907,7 +910,7 @@
  	struct rose_component *comp = NULL;
  	unsigned char *vdata = data;
  
-@@ -404,9 +436,7 @@
+@@ -546,9 +578,7 @@
  		switch(comp->type) {
  		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):		/* [0] presentationAllowedNumber */
  			value->pres = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
@@ -918,7 +921,7 @@
  		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1):		/* [1] IMPLICIT presentationRestricted */
  			if (comp->len != 0) { /* must be NULL */
  				pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n");
-@@ -423,9 +453,7 @@
+@@ -565,9 +595,7 @@
  			return 2;
  		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):		/* [3] presentationRestrictedNumber */
  			value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
@@ -929,7 +932,7 @@
  		default:
  			pri_message(pri, "Invalid PresentedNumberUnscreened component 0x%X\n", comp->type);
  		}
-@@ -436,7 +464,7 @@
+@@ -578,7 +606,7 @@
  	return -1;
  }
  
@@ -938,7 +941,7 @@
  {
  	int i = 0;
  	int diversion_counter;
-@@ -445,21 +473,9 @@
+@@ -587,21 +615,9 @@
  	struct addressingdataelements_presentednumberunscreened divertingnr;
   	struct addressingdataelements_presentednumberunscreened originalcallednr;
  	struct rose_component *comp = NULL;
@@ -961,7 +964,7 @@
  	do {
  		/* diversionCounter stuff */
  		GET_COMPONENT(comp, i, vdata, len);
-@@ -477,20 +493,18 @@
+@@ -619,20 +635,18 @@
  	
  		if(pri->debug & PRI_DEBUG_APDU)
  			pri_message(pri, "    Redirection reason: %d, total diversions: %d\n", diversion_reason, diversion_counter);
@@ -985,7 +988,7 @@
  				comp->len = res;
  				if (res < 0)
  					return -1;
-@@ -499,43 +513,33 @@
+@@ -641,43 +655,33 @@
  					pri_message(pri, "      ton = %d, pres = %d, npi = %d\n", divertingnr.ton, divertingnr.pres, divertingnr.npi);
  				}
  				break;
@@ -1036,7 +1039,7 @@
  
  		if (divertingnr.pres >= 0) {
  			call->redirectingplan = divertingnr.npi;
-@@ -548,15 +552,19 @@
+@@ -690,15 +694,19 @@
  			call->origcalledpres = originalcallednr.pres;
  			libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));
  		}
@@ -1059,8 +1062,8 @@
  static int rose_diverting_leg_information2_encode(struct pri *pri, q931_call *call)
  {
  	int i = 0, j, compsp = 0;
-@@ -694,6 +702,64 @@
- 	return 0;
+@@ -916,6 +924,131 @@
+ 		return 0;
  }
  
 +/* Call deflection */
@@ -1121,10 +1124,77 @@
 +        return 0;
 +}
 +
++/* Call rerouting */
++int add_call_rerouting_facility_ie(struct pri *pri, q931_call *c, char *destination) {
++    int i = 0, j, compsp = 0;
++    struct rose_component *comp, *compstk[10];
++    unsigned char buffer[256];
++    unsigned char bcie[5] = { 0x04, 0x03, 0x90, 0x90, 0xA3 };
++
++    buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_ROSE);
++    /* invoke */
++    ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
++    ASN1_PUSH(compstk, compsp, comp);
++
++    ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
++    ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_CALLREROUTING); 
++
++    /* Argument sequence */
++    ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
++    ASN1_PUSH(compstk, compsp, comp);
++
++	/* DIVERSION REASON (CFU) */
++	ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 1);
++
++	/* arg.Address */
++	ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
++        ASN1_PUSH(compstk, compsp, comp);
++
++	    j = asn1_string_encode(0x80, &buffer[i], sizeof(buffer)-i, 20, destination, strlen(destination));
++	    if(j<0) return -1;
++	    i += j;
++
++	/* close Address */
++	ASN1_FIXUP(compstk, compsp, buffer, i);
++
++	/* add rerouting counter tag */
++	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, 1);
++
++
++	    /* IE tag */
++	    j = asn1_string_encode(ASN1_APPLICATION, &buffer[i], sizeof(buffer)-i, 5, bcie, 5);
++	    if(j<0) return -1;
++	    i += j;
++
++	/* last rerouting number */
++	ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
++	ASN1_PUSH(compstk, compsp, comp);
++
++	/* presented number unscreened */
++	ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
++	ASN1_PUSH(compstk, compsp, comp);
++
++	    j = asn1_string_encode(0x80, &buffer[i], sizeof(buffer)-i, 20, c->callednum, strlen(c->callednum)); 
++	    if(j<0) return -1;
++	    i += j;
++
++	/* close Address */
++	ASN1_FIXUP(compstk, compsp, buffer, i);
++
++    /* Fix length of stacked components */
++    while(compsp > 0) {
++        ASN1_FIXUP(compstk, compsp, buffer, i);
++    }
++    if (pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL))
++                     return -1;
++   
++        return 0;
++}
++
  /* Sending callername information functions */
  static int add_callername_facility_ies(struct pri *pri, q931_call *c, int cpe)
  {
-@@ -936,7 +1002,7 @@
+@@ -1162,7 +1295,7 @@
  		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "!! Invalid AOC Charging Request argument. Expected Enumerated (0x0A) but Received 0x%02X\n");
  		ASN1_GET_INTEGER(comp, chargingcase);				
  		if (chargingcase >= 0 && chargingcase <= 2) {
@@ -1133,7 +1203,7 @@
  				pri_message(pri, "Channel %d/%d, Call %d  - received AOC charging request - charging case: %i\n", 
  					call->ds1no, call->channelno, call->cr, chargingcase);
  		} else {
-@@ -1054,7 +1120,7 @@
+@@ -1280,7 +1413,7 @@
  	return 0;
  }
  
@@ -1142,14 +1212,14 @@
  {
  	/* sample data: [ 91 a1 12 02 02 3a 78 02 01 24 30 09 30 07 a1 05 30 03 02 01 01 ] */
  	int i = 0, res = 0, compsp = 0;
-@@ -1108,18 +1174,20 @@
+@@ -1334,20 +1467,21 @@
  		dump_apdu (pri, buffer, i);
  		
  	/* code below is untested */
 -	res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL);
 +	res = pri_call_apdu_queue(c, msgtype, buffer, i, NULL, NULL);
  	if (res) {
- 		pri_message(pri, "Could not queue ADPU in facility message\n");
+ 		pri_message(pri, "Could not queue APDU in facility message\n");
  		return -1;
  	}
  
@@ -1166,9 +1236,11 @@
  		return -1;
 +	    }
  	}
- 
+-
  	return 0;
-@@ -1152,13 +1220,15 @@
+ }
+ /* End AOC */
+@@ -1572,13 +1706,15 @@
  		NEXT_COMPONENT(comp, i);
  
  		/* No argument - return with error */
@@ -1189,7 +1261,7 @@
  
  		if (pri->debug & PRI_DEBUG_APDU)
  			pri_message(pri, "  [ Handling operation %d ]\n", operation_tag);
-@@ -1182,7 +1252,11 @@
+@@ -1602,7 +1738,11 @@
  		case ROSE_DIVERTING_LEG_INFORMATION2:
  			if (pri->debug & PRI_DEBUG_APDU)
  				pri_message(pri, "  Handle DivertingLegInformation2\n");
@@ -1202,7 +1274,7 @@
  		case ROSE_AOC_NO_CHARGING_INFO_AVAILABLE:
  			if (pri->debug & PRI_DEBUG_APDU) {
  				pri_message(pri, "ROSE %i: AOC No Charging Info Available - not handled!", operation_tag);
-@@ -1210,6 +1284,7 @@
+@@ -1630,6 +1770,7 @@
  			}
  			return -1;
  		case ROSE_AOC_AOCD_CHARGING_UNIT:
@@ -1210,7 +1282,7 @@
  			if (pri->debug & PRI_DEBUG_APDU) {
  				pri_message(pri, "ROSE %i: AOC-D Charging Unit - not handled!", operation_tag);
  				dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
-@@ -1224,7 +1299,7 @@
+@@ -1644,7 +1785,7 @@
  		case ROSE_AOC_AOCE_CHARGING_UNIT:
  			return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
  			if (0) { /* the following function is currently not used - just to make the compiler happy */
@@ -1219,7 +1291,7 @@
  				return 0;
  			}
  		case ROSE_AOC_IDENTIFICATION_OF_CHARGE:
-@@ -1233,6 +1308,22 @@
+@@ -1653,6 +1794,22 @@
  				dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
  			}
  			return -1;
@@ -1242,9 +1314,9 @@
  		default:
  			if (pri->debug & PRI_DEBUG_APDU) {
  				pri_message(pri, "!! Unable to handle ROSE operation %d", operation_tag);
-diff -urN libpri-1.2.4.orig/pri_facility.h libpri-1.2.4/pri_facility.h
---- libpri-1.2.4.orig/pri_facility.h	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pri_facility.h	2006-04-15 21:35:05.000000000 +0200
+diff -urN libpri-1.4.1.orig/pri_facility.h libpri-1.4.1/pri_facility.h
+--- libpri-1.4.1.orig/pri_facility.h	2006-02-14 20:22:26.000000000 +0100
++++ libpri-1.4.1/pri_facility.h	2007-07-11 14:25:15.000000000 +0200
 @@ -34,7 +34,7 @@
  /* Operation ID values */
  /* Q.952 ROSE operations (Diverting) */
@@ -1254,7 +1326,7 @@
  #define ROSE_DIVERTING_LEG_INFORMATION3		19
  /* Q.956 ROSE operations (Advice Of Charge) */
  #define ROSE_AOC_NO_CHARGING_INFO_AVAILABLE	26
-@@ -48,11 +48,15 @@
+@@ -48,11 +48,16 @@
  #define ROSE_AOC_IDENTIFICATION_OF_CHARGE	37
  /* Q.SIG operations */
  #define SS_CNID_CALLINGNAME					0
@@ -1265,13 +1337,14 @@
  #define SS_MWI_INTERROGATE					82
  
 +#define ROSE_CALLDEFLECTION			0x0D
++#define ROSE_CALLREROUTING			0x0E
 +#define ROSE_EXPLICIT_CALL_TRANSFER		0x06
 +#define ROSE_MALICIOUS_CID			0x31
 +
  /* ROSE definitions and data structures */
  #define INVOKE_IDENTIFIER			0x02
  #define INVOKE_LINKED_IDENTIFIER	0x80
-@@ -180,12 +184,6 @@
+@@ -186,12 +191,6 @@
  			(variable) = ((variable) << 8) | (component)->data[comp_idx]; \
  	} while (0)
  
@@ -1284,18 +1357,20 @@
  #define ASN1_ADD_SIMPLE(component, comptype, ptr, idx) \
  	do { \
  		(component) = (struct rose_component *)&((ptr)[(idx)]); \
-@@ -260,4 +258,8 @@
- /* Adds the "standard" ADPUs to a call */
- extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
+@@ -279,4 +278,10 @@
  
+ int asn1_dump(struct pri *pri, void *comp, int len);
+ 
 +extern int add_call_deflection_facility_ie(struct pri *pri, q931_call *c, char *destination);
 +
++extern int add_call_rerouting_facility_ie(struct pri *pri, q931_call *c, char *destination);
++
 +extern int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits, int send_facility_message);
 +
  #endif /* _PRI_FACILITY_H */
-diff -urN libpri-1.2.4.orig/pri_internal.h libpri-1.2.4/pri_internal.h
---- libpri-1.2.4.orig/pri_internal.h	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pri_internal.h	2006-04-15 21:57:19.000000000 +0200
+diff -urN libpri-1.4.1.orig/pri_internal.h libpri-1.4.1/pri_internal.h
+--- libpri-1.4.1.orig/pri_internal.h	2006-06-07 00:06:52.000000000 +0200
++++ libpri-1.4.1/pri_internal.h	2007-07-11 14:25:15.000000000 +0200
 @@ -5,6 +5,8 @@
   *
   * Copyright (C) 2001, Linux Support Services, Inc.
@@ -1305,7 +1380,7 @@
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
-@@ -30,7 +32,10 @@
+@@ -33,7 +35,10 @@
  struct pri_sched {
  	struct timeval when;
  	void (*callback)(void *data);
@@ -1316,7 +1391,7 @@
  };
  
  struct q921_frame;
-@@ -38,8 +43,15 @@
+@@ -41,8 +46,15 @@
  enum q931_mode;
  
  /* No more than 128 scheduled events */
@@ -1332,7 +1407,7 @@
  #define MAX_TIMERS 32
  
  struct pri {
-@@ -51,6 +63,7 @@
+@@ -54,6 +66,7 @@
  	struct pri *master;		/* Master channel if appropriate */
  	struct pri_sched pri_sched[MAX_SCHED];	/* Scheduled events */
  	int debug;			/* Debug stuff */
@@ -1340,7 +1415,7 @@
  	int state;			/* State of D-channel */
  	int switchtype;		/* Switch type */
  	int nsf;		/* Network-Specific Facility (if any) */
-@@ -62,25 +75,42 @@
+@@ -65,25 +78,42 @@
  	int protodisc;
  	
  	/* Q.921 State */
@@ -1400,7 +1475,7 @@
  	/* All ISDN Timer values */
  	int timers[MAX_TIMERS];
  
-@@ -89,8 +119,8 @@
+@@ -92,8 +122,8 @@
  	int schedev;
  	pri_event ev;		/* Static event thingy */
  	
@@ -1411,7 +1486,7 @@
  	
  	/* Q.931 calls */
  	q931_call **callpool;
-@@ -109,6 +139,9 @@
+@@ -112,6 +142,9 @@
  
  	unsigned char last_invoke;	/* Last ROSE invoke ID */
  	unsigned char sendfacility;
@@ -1421,7 +1496,7 @@
  };
  
  struct pri_sr {
-@@ -118,6 +151,7 @@
+@@ -121,6 +154,7 @@
  	int nonisdn;
  	char *caller;
  	int callerplan;
@@ -1429,15 +1504,15 @@
  	char *callername;
  	int callerpres;
  	char *called;
-@@ -130,6 +164,7 @@
+@@ -133,6 +167,7 @@
  	int redirectingreason;
  	int justsignalling;
- 	char *useruserinfo;
+ 	const char *useruserinfo;
 +	char *llc;
+ 	int transferable;
  };
  
- /* Internal switch types */
-@@ -167,8 +202,13 @@
+@@ -171,8 +206,13 @@
  	
  	int alive;			/* Whether or not the call is alive */
  	int acked;			/* Whether setup has been acked or not */
@@ -1451,30 +1526,16 @@
  	
  	int ri;				/* Restart Indicator (Restart Indicator IE) */
  
-@@ -202,15 +242,18 @@
- 	int callerplan;
- 	int callerplanani;
- 	int callerpres;			/* Caller presentation */
--	char callerani[256];	/* Caller */
--	char callernum[256];
-+ 	int callerplanuser;
-+ 	int callerpresuser;			/* Caller presentation */
-+ 	char callernum[256];	/* Calling Number (network provided) */
-+ 	char callerani[256];	/* Calling Number, (user provided) */
-+
+@@ -209,6 +249,8 @@
+ 	char callerani[256];	/* Caller */
+ 	char callernum[256];
  	char callername[256];
++ 	int callerplanuser;
++ 	int callerpresuser;
  
--	char digitbuf[64];		/* Buffer for digits that come in KEYPAD_FACILITY */
-+	char digitbuf[64];	/* Buffer for digits that come in KEYPAD_FACILITY */
+ 	char keypad_digits[64];		/* Buffer for digits that come in KEYPAD_FACILITY */
  
- 	int ani2;               /* ANI II */
- 	
--	int calledplan;
-+	int  calledplan;
- 	int nonisdn;
- 	char callednum[256];	/* Called Number */
- 	int complete;			/* no more digits coming */
-@@ -225,23 +268,36 @@
+@@ -229,6 +271,9 @@
  	char redirectingnum[256];	/* Number of redirecting party */
  	char redirectingname[256];	/* Name of redirecting party */
  
@@ -1484,14 +1545,8 @@
  	/* Filled in cases of multiple diversions */
  	int origcalledplan;
  	int origcalledpres;
--	int origredirectingreason;	/* Original reason for redirect (in cases of multiple redirects) */
-+	int origredirectingreason;      /* Original reason for redirect (in cases of multiple redirects) */
- 	char origcalledname[256];	/* Original name of person being called */
--	char origcallednum[256];	/* Orignal number of person being called */
-+	char origcallednum[256];		/* Orignal number of person being called */
- 
--	int useruserprotocoldisc;
-+        int useruserprotocoldisc;
+@@ -239,17 +284,28 @@
+ 	int useruserprotocoldisc;
  	char useruserinfo[256];
  	char callingsubaddr[256];	/* Calling parties sub address */
 +
@@ -1505,16 +1560,21 @@
  	
  	long aoc_units;				/* Advice of Charge Units */
  
-+	char llc[16]; /* low layer compatibility */
  	struct apdu_event *apdus;	/* APDU queue for call */
+ 
++	char llc[16]; /* low layer compatibility */
+ 	int transferable;
+ 	unsigned int rlt_call_id;	/* RLT call id */
  };
  
  extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
-+extern int pri_schedule_event2(struct pri *pri, int ms, void (*function)(void *data, int data2), void *data, int data2);
  
++extern int pri_schedule_event2(struct pri *pri, int ms, void (*function)(void *data, int data2), void *data, int data2);
++
  extern pri_event *pri_schedule_run(struct pri *pri);
  
-@@ -250,7 +306,7 @@
+ extern void pri_schedule_del(struct pri *pri, int ev);
+@@ -257,7 +313,7 @@
  extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
  
  extern void pri_message(struct pri *pri, char *fmt, ...);
@@ -1523,9 +1583,9 @@
  extern void pri_error(struct pri *pri, char *fmt, ...);
  
  void libpri_copy_string(char *dst, const char *src, size_t size);
-diff -urN libpri-1.2.4.orig/pri_q921.h libpri-1.2.4/pri_q921.h
---- libpri-1.2.4.orig/pri_q921.h	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pri_q921.h	2006-04-15 21:57:24.000000000 +0200
+diff -urN libpri-1.4.1.orig/pri_q921.h libpri-1.4.1/pri_q921.h
+--- libpri-1.4.1.orig/pri_q921.h	2006-02-14 20:22:26.000000000 +0100
++++ libpri-1.4.1/pri_q921.h	2007-07-11 14:25:15.000000000 +0200
 @@ -5,6 +5,8 @@
   *
   * Copyright (C) 2001, Linux Support Services, Inc.
@@ -1567,9 +1627,9 @@
 +extern int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr, int tei);
  
  #endif
-diff -urN libpri-1.2.4.orig/pri_q931.h libpri-1.2.4/pri_q931.h
---- libpri-1.2.4.orig/pri_q931.h	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pri_q931.h	2006-04-15 21:57:29.000000000 +0200
+diff -urN libpri-1.4.1.orig/pri_q931.h libpri-1.4.1/pri_q931.h
+--- libpri-1.4.1.orig/pri_q931.h	2006-07-06 23:11:37.000000000 +0200
++++ libpri-1.4.1/pri_q931.h	2007-07-11 14:25:15.000000000 +0200
 @@ -5,6 +5,8 @@
   *
   * Copyright (C) 2001, Linux Support Services, Inc.
@@ -1599,18 +1659,18 @@
  
  /* Call state stuff */
  #define Q931_CALL_STATE_NULL				0
-@@ -243,7 +251,7 @@
- /* EuroISDN  */
- #define Q931_SENDING_COMPLETE		0xa1
+@@ -247,7 +255,7 @@
+ /* Q.SIG specific */
+ #define QSIG_IE_TRANSIT_COUNT		0x31
  
 -extern int q931_receive(struct pri *pri, q931_h *h, int len);
 +extern int q931_receive(struct pri *pri, q931_h *h, int len, int tei);
  
  extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
  
-@@ -257,6 +265,10 @@
+@@ -263,6 +271,10 @@
  
- extern int q931_information(struct pri *pri, q931_call *call, char digit);
+ extern int q931_keypad_facility(struct pri *pri, q931_call *call, char *digits);
  
 +extern int q931_information_display(struct pri *pri, q931_call *call, char *display);
 +
@@ -1619,7 +1679,7 @@
  extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
  
  extern int q931_release(struct pri *pri, q931_call *call, int cause);
-@@ -265,6 +277,10 @@
+@@ -271,6 +283,10 @@
  
  extern int q931_hangup(struct pri *pri, q931_call *call, int cause);
  
@@ -1630,17 +1690,16 @@
  extern int q931_restart(struct pri *pri, int channel);
  
  extern int q931_facility(struct pri *pri, q931_call *call);
-@@ -279,5 +295,23 @@
- extern void q931_dump(struct pri *pri, q931_h *h, int len, int txrx);
+@@ -286,6 +302,22 @@
  
  extern void __q931_destroycall(struct pri *pri, q931_call *c);
-+ 
+ 
 +extern int q931_hold_acknowledge(struct pri *pri, q931_call *c);
 +
 +extern int q931_hold_reject(struct pri *pri, q931_call *c);
 +
 +extern int q931_retrieve_acknowledge(struct pri *pri, q931_call *c, int channel);
- 	
++	
 +extern int q931_retrieve_reject(struct pri *pri, q931_call *c);
 +
 +extern int q931_suspend_acknowledge(struct pri *pri, q931_call *c, char *display);
@@ -1651,12 +1710,12 @@
 +
 +extern int q931_resume_acknowledge(struct pri *pri, q931_call *c, int channel, char *display);
 +
-+//extern int q931_facility(struct pri *pri, q931_call *c, int operation, char *arguments);
-+
+ extern void q931_dl_indication(struct pri *pri, int event);
+ 
  #endif
-diff -urN libpri-1.2.4.orig/prisched.c libpri-1.2.4/prisched.c
---- libpri-1.2.4.orig/prisched.c	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/prisched.c	2006-04-15 21:57:42.000000000 +0200
+diff -urN libpri-1.4.1.orig/prisched.c libpri-1.4.1/prisched.c
+--- libpri-1.4.1.orig/prisched.c	2006-02-14 20:22:26.000000000 +0100
++++ libpri-1.4.1/prisched.c	2007-07-11 14:25:15.000000000 +0200
 @@ -1,10 +1,12 @@
  /*
   * libpri: An implementation of Primary Rate ISDN
@@ -1793,9 +1852,9 @@
 +	pri->pri_sched[id].callback2 = NULL;
  }
 +
-diff -urN libpri-1.2.4.orig/pritest.c libpri-1.2.4/pritest.c
---- libpri-1.2.4.orig/pritest.c	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pritest.c	2006-01-18 12:28:07.000000000 +0100
+diff -urN libpri-1.4.1.orig/pritest.c libpri-1.4.1/pritest.c
+--- libpri-1.4.1.orig/pritest.c	2006-07-05 18:17:05.000000000 +0200
++++ libpri-1.4.1/pritest.c	2007-07-11 14:25:15.000000000 +0200
 @@ -1,9 +1,9 @@
  /*
   * libpri: An implementation of Primary Rate ISDN
@@ -1808,7 +1867,7 @@
   * All Rights Reserved.
   *
   * This program is free software; you can redistribute it and/or modify
-@@ -51,8 +51,8 @@
+@@ -47,8 +47,8 @@
  #define PRI_DEF_NODETYPE	PRI_CPE
  #define PRI_DEF_SWITCHTYPE	PRI_SWITCH_NI2
  
@@ -1819,7 +1878,7 @@
  
  
  static int offset = 0;
-@@ -60,7 +60,7 @@
+@@ -56,7 +56,7 @@
  static void do_channel(ZAP *z)
  {
  	/* This is the part that runs on a given channel */
@@ -1828,7 +1887,7 @@
  }
  
  struct pri_chan {
-@@ -76,6 +76,14 @@
+@@ -72,6 +72,14 @@
  		return PRI_CPE;
  	if (!strcasecmp(node, "network"))
  		return PRI_NETWORK;
@@ -1843,7 +1902,7 @@
  	return -1;
  }
  
-@@ -285,6 +293,10 @@
+@@ -281,6 +289,10 @@
  		}
  		
  		break;
@@ -1854,11 +1913,14 @@
  	default:
  		fprintf(stderr, "--!! Unknown PRI event %d\n", e->e);
  	}
-diff -urN libpri-1.2.4.orig/pri_timers.h libpri-1.2.4/pri_timers.h
---- libpri-1.2.4.orig/pri_timers.h	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/pri_timers.h	2006-01-18 12:28:07.000000000 +0100
-@@ -27,17 +27,17 @@
+diff -urN libpri-1.4.1.orig/pri_timers.h libpri-1.4.1/pri_timers.h
+--- libpri-1.4.1.orig/pri_timers.h	2006-02-14 20:22:26.000000000 +0100
++++ libpri-1.4.1/pri_timers.h	2007-07-11 14:25:15.000000000 +0200
+@@ -25,19 +25,51 @@
+ #ifndef _PRI_TIMERS_H
+ #define _PRI_TIMERS_H
  
++#ifdef RELAXED_TIMERS
  /* -1 means we dont currently support the timer/counter */
  #define PRI_TIMERS_DEFAULT {	3,	/* N200 */ \
 -				-1,	/* N201 */ \
@@ -1876,13 +1938,52 @@
  				-1,	/* T301 */ \
  				-1,	/* T302 */ \
 -				-1,	/* T303 */ \
++				6000,	/* T303 */ \
++				-1,	/* T304 */ \
++				30000,	/* T305 */ \
++				-1,	/* T306 */ \
++				-1,	/* T307 */ \
++				6000,	/* T308 */ \
++				-1,	/* T309 */ \
++				-1,	/* T310 */ \
++				4000,	/* T313 */ \
++				-1,	/* T314 */ \
++				-1,	/* T316 */ \
++				-1,	/* T317 */ \
++				-1,	/* T318 */ \
++				-1,	/* T319 */ \
++				-1,	/* T320 */ \
++				-1,	/* T321 */ \
++				-1	/* T322 */ \
++			}
++#else
++/* -1 means we dont currently support the timer/counter */
++#define PRI_TIMERS_DEFAULT {	3,	/* N200 */ \
++				260,	/* N201 */ \
++				3,	/* N202 */ \
++				7,	/* K */ \
++				1000,	/* T200 */ \
++				2000,	/* T201 */ \
++				5000,	/* T202 */ \
++				10000,	/* T203 */ \
++				-1,	/* T300 */ \
++				-1,	/* T301 */ \
++				-1,	/* T302 */ \
 +				4000,	/* T303 */ \
  				-1,	/* T304 */ \
  				30000,	/* T305 */ \
  				-1,	/* T306 */ \
-diff -urN libpri-1.2.4.orig/q921.c libpri-1.2.4/q921.c
---- libpri-1.2.4.orig/q921.c	2005-12-06 22:35:50.000000000 +0100
-+++ libpri-1.2.4/q921.c	2006-08-01 09:55:53.000000000 +0200
+@@ -55,6 +87,7 @@
+ 				-1,	/* T321 */ \
+ 				-1	/* T322 */ \
+ 			}
++#endif
+ 
+ /* XXX Only our default timers are setup now XXX */
+ #define PRI_TIMERS_UNKNOWN PRI_TIMERS_DEFAULT
+diff -urN libpri-1.4.1.orig/q921.c libpri-1.4.1/q921.c
+--- libpri-1.4.1.orig/q921.c	2006-07-06 23:11:37.000000000 +0200
++++ libpri-1.4.1/q921.c	2007-07-11 14:25:15.000000000 +0200
 @@ -1,10 +1,12 @@
  /*
   * libpri: An implementation of Primary Rate ISDN
@@ -2253,7 +2354,7 @@
 +    }
 +}
 +
-+  static void q921_send_teiremove(struct pri *pri, int tei) {
++static void q921_send_teiremove(struct pri *pri, int tei) {
 +      q921_u *f;
 +      unsigned short ri=0x6464;
 +      ri = rand();
@@ -2284,9 +2385,9 @@
 +  	q921_transmit(pri,(q921_h *)&(f->h),8);
 +  	free(f);
 +      }
-+  }
++}
 +  
-+  static void q921_send_teidenied(struct pri *pri, int ri, int tei) {
++static void q921_send_teidenied(struct pri *pri, int ri, int tei) {
 +      q921_u *f;
 +  
 +      if (pri->localtype != BRI_NETWORK_PTMP) {
@@ -2315,7 +2416,7 @@
 +  	q921_transmit(pri,(q921_h *)&(f->h),8);
 +  	free(f);
 +      }
-+  }
++}
 +  
 + 
 +static void q921_send_sabme_now(void *vpri, int tei);
@@ -2356,7 +2457,7 @@
  	h.u.m3 = 3;	/* M3 = 3 */
  	h.u.m2 = 3;	/* M2 = 3 */
  	h.u.p_f = 1;	/* Poll bit set */
-@@ -139,25 +510,42 @@
+@@ -139,27 +510,44 @@
  	case PRI_CPE:
  		h.h.c_r = 0;
  		break;
@@ -2378,11 +2479,14 @@
 +		pri_error(pri, "Don't know how to send SABME on a type %d node\n", pri->localtype);
  		return;
  	}
- 	if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 	if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
  		pri_message(pri, "Sending Set Asynchronous Balanced Mode Extended\n");
  	q921_transmit(pri, &h, 3);
+-	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_AWAITING_ESTABLISH)
++	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state[teio] != Q921_AWAITING_ESTABLISH)
+ 		pri_message(pri, DBGHEAD "q921_state now is Q921_AWAITING_ESTABLISH\n", DBGINFO);
 -	pri->q921_state = Q921_AWAITING_ESTABLISH;
-+ 	pri->q921_state[teio] = Q921_AWAITING_ESTABLISH;
++	pri->q921_state[teio] = Q921_AWAITING_ESTABLISH;
  }
  
 -static void q921_send_sabme_now(void *vpri)
@@ -2391,27 +2495,27 @@
 -	q921_send_sabme(vpri, 1);
 +	q921_send_sabme(vpri, 1, tei);
  }
++  
  
 -static int q921_ack_packet(struct pri *pri, int num)
-+  
-+
 +static int q921_ack_packet(struct pri *pri, int num, int tei)
  {
  	struct q921_frame *f, *prev = NULL;
 -	f = pri->txqueue;
-+	int teio=tei - Q921_TEI_BASE;
++ 	int teio=tei - Q921_TEI_BASE;
 +	if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
 +	f = pri->txqueue[teio];
++
  	while(f) {
  		if (f->h.n_s == num) {
  			/* Cancel each packet as necessary */
-@@ -165,26 +553,26 @@
+@@ -167,26 +555,26 @@
  			if (prev)
  				prev->next = f->next;
  			else
 -				pri->txqueue = f->next;
 +				pri->txqueue[teio] = f->next;
- 			if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 			if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -				pri_message(pri, "-- ACKing packet %d, new txqueue is %d (-1 means empty)\n", f->h.n_s, pri->txqueue ? pri->txqueue->h.n_s : -1);
 +				pri_message(pri, "-- ACKing packet %d, new txqueue is %d (-1 means empty)\n", f->h.n_s, pri->txqueue[teio] ? pri->txqueue[teio]->h.n_s : -1);
  			/* Update v_a */
@@ -2430,7 +2534,7 @@
  			while(f) {
  				if (!f->transmitted) {
  					/* Send it now... */
- 					if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 					if (pri->debug & PRI_DEBUG_Q921_DUMP)
  						pri_message(pri, "-- Finally transmitting %d, since window opened up\n", f->h.n_s);
  					f->transmitted++;
 -					pri->windowlen++;
@@ -2440,7 +2544,7 @@
  					q921_transmit(pri, (q921_h *)(&f->h), f->len);
  					break;
  				}
-@@ -198,77 +586,136 @@
+@@ -200,77 +588,130 @@
  	return 0;
  }
  
@@ -2472,7 +2576,7 @@
  {
 -	if (pri->t203_timer) {
 -		pri_schedule_del(pri, pri->t203_timer);
--		if (pri->debug &  PRI_DEBUG_Q921_STATE)
+-		if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -			pri_message(pri, "-- Restarting T203 counter\n");
 -		/* Nothing to transmit, start the T203 counter instead */
 -		pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
@@ -2541,7 +2645,7 @@
  		return ev;
  	}
  	/* Cancel each packet as necessary */
- 	if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 	if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -		pri_message(pri, "-- ACKing all packets from %d to (but not including) %d\n", pri->v_a, ack);
 -	for (x=pri->v_a; x != ack; Q921_INC(x)) 
 -		cnt += q921_ack_packet(pri, x);	
@@ -2551,11 +2655,9 @@
 +		cnt += q921_ack_packet(pri, x, tei);	
 +	if (!pri->txqueue[teio]) {
 +		/* Something was ACK'd.  Stop T200 counter */
-+		if (pri->t200_timer[teio]) {
-+		    pri_schedule_del(pri, pri->t200_timer[teio]);
-+		    pri->t200_timer[teio] = 0;
-+		}
- 		if (pri->debug &  PRI_DEBUG_Q921_STATE)
++		pri_schedule_del(pri, pri->t200_timer[teio]);
++		pri->t200_timer[teio] = 0;
+ 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
  			pri_message(pri, "-- Since there was nothing left, stopping T200 counter\n");
 -		/* Something was ACK'd.  Stop T200 counter */
 -		pri_schedule_del(pri, pri->t200_timer);
@@ -2565,7 +2667,7 @@
 +	if (pri->t203_timer[teio]) {
 +		pri_schedule_del(pri, pri->t203_timer[teio]);
 +		pri->t203_timer[teio] = 0;
- 		if (pri->debug &  PRI_DEBUG_Q921_STATE)
+ 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
  			pri_message(pri, "-- Stopping T203 counter since we got an ACK\n");
 -		pri_schedule_del(pri, pri->t203_timer);
 -		pri->t203_timer = 0;
@@ -2573,19 +2675,15 @@
 -	if (pri->txqueue) {
 +	if (pri->txqueue[teio]) {
  		/* Something left to transmit, Start the T200 counter again if we stopped it */
-+		if (pri->t200_timer[teio]) {
-+		    pri_schedule_del(pri, pri->t200_timer[teio]);
-+		    pri->t200_timer[teio] = 0;
-+		}
- 		if (pri->debug &  PRI_DEBUG_Q921_STATE)
+ 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -			pri_message(pri, "-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue->h.n_s);
 -		if (!pri->t200_timer)
 -			pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
 +			pri_message(pri, "-- Something left to transmit (%d), restarting T200 counter\n", pri->txqueue[teio]->h.n_s);
-+		pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-+
++		if (!pri->t200_timer[teio])
++			pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
  	} else {
- 		if (pri->debug &  PRI_DEBUG_Q921_STATE)
+ 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
  			pri_message(pri, "-- Nothing left, starting T203 counter\n");
  		/* Nothing to transmit, start the T203 counter instead */
 -		pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
@@ -2609,7 +2707,7 @@
  	h.s.p_f = pf;	
  	switch(pri->localtype) {
  	case PRI_NETWORK:
-@@ -277,23 +724,38 @@
+@@ -279,23 +720,38 @@
  	case PRI_CPE:
  		h.h.c_r = 1;
  		break;
@@ -2631,7 +2729,7 @@
 +		pri_error(pri, "Don't know how to REJECT on a type %d node\n", pri->localtype);
  		return;
  	}
- 	if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 	if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -		pri_message(pri, "Sending Reject (%d)\n", pri->v_r);
 -	pri->sentrej = 1;
 +		pri_message(pri, "Sending Reject (%d)\n", pri->v_r[teio]);
@@ -2653,7 +2751,7 @@
  	h.s.p_f = pbit;		/* Poll/Final set appropriately */
  	switch(pri->localtype) {
  	case PRI_NETWORK:
-@@ -308,81 +770,192 @@
+@@ -310,85 +766,190 @@
  		else
  			h.h.c_r = 1;
  		break;
@@ -2690,7 +2788,7 @@
  	}
 -	pri->v_na = pri->v_r;	/* Make a note that we've already acked this */
 +	pri->v_na[teio] = pri->v_r[teio];	/* Make a note that we've already acked this */
- 	if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 	if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -		pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r);
 +		pri_message(pri, "Sending Receiver Ready (%d)\n", pri->v_r[teio]);
  	q921_transmit(pri, &h, 4);
@@ -2703,56 +2801,51 @@
 -	if (pri->txqueue) {
 + 	int teio=tei - Q921_TEI_BASE;
 + 	if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+ 	if (pri->txqueue[teio]) {
++	if (pri->txqueue[teio]) {
  		/* Retransmit first packet in the queue, setting the poll bit */
- 		if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
  			pri_message(pri, "-- T200 counter expired, What to do...\n");
--		/* Force Poll bit */
+ 		/* Force Poll bit */
 -		pri->txqueue->h.p_f = 1;	
--		/* Update nr */
++		pri->txqueue[teio]->h.p_f = 1;	
+ 		/* Update nr */
 -		pri->txqueue->h.n_r = pri->v_r;
 -		pri->v_na = pri->v_r;
 -		pri->solicitfbit = 1;
 -		pri->retrans++;
-+		if (pri->txqueue[teio]->transmitted) {
-+		    /* Force Poll bit, if this is a retransmission */
-+		    pri->txqueue[teio]->h.p_f = 1;	
-+		    pri->solicitfbit[teio] = 1;
-+		    /* Update nr */
-+		    pri->txqueue[teio]->h.n_r = pri->v_r[teio];
-+		    pri->v_na[teio] = pri->v_r[teio];
-+		    pri->retrans[teio]++;
-+		}
++		pri->txqueue[teio]->h.n_r = pri->v_r[teio];
++		pri->v_na[teio] = pri->v_r[teio];
++		pri->solicitfbit[teio] = 1;
++		pri->retrans[teio]++;
        /* Up to three retransmissions */
 -      if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
-+      if ((pri->retrans[teio] + 1)  <= pri->timers[PRI_TIMER_N200]) {
++      if (pri->retrans[teio] + 1 < pri->timers[PRI_TIMER_N200]) {
           /* Reschedule t200_timer */
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
+          if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -            pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue->len);
 -		if (pri->busy) 
 -			q921_rr(pri, 1, 1);
--		else {
--			if (!pri->txqueue->transmitted) 
-+        	pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue[teio]->len);
-+		if (pri->busy[teio]) {
-+        	// pri_message(pri, "-- q921_rr(pri, 1, 1) \n", tei);
++            pri_message(pri, "-- Retransmitting %d bytes\n", pri->txqueue[teio]->len);
++		if (pri->busy[teio]) 
 +			q921_rr(pri, 1, 1, tei);
-+		} else {
-+			if (!pri->txqueue[teio]->transmitted)
+ 		else {
+-			if (!pri->txqueue->transmitted) 
++			if (!pri->txqueue[teio]->transmitted) 
  				pri_error(pri, "!! Not good - head of queue has not been transmitted yet\n");
 -			q921_transmit(pri, (q921_h *)&pri->txqueue->h, pri->txqueue->len);
 +			q921_transmit(pri, (q921_h *)&pri->txqueue[teio]->h, pri->txqueue[teio]->len);
-+	    //layer 3
-+			pri->txqueue[teio]->transmitted++;
  		}
-          if (pri->debug & PRI_DEBUG_Q921_STATE) 
+          if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -               pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans);
 -         pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
 +               pri_message(pri, "-- Rescheduling retransmission (%d)\n", pri->retrans[teio]);
 +         pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
        } else {
-          if (pri->debug & PRI_DEBUG_Q921_STATE) 
+          if (pri->debug & PRI_DEBUG_Q921_STATE)
                 pri_message(pri, "-- Timeout occured, restarting PRI\n");
+-	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)
++	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state[teio] != Q921_LINK_CONNECTION_RELEASED)
+ 		pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n",DBGINFO);
 -         pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
 -      	pri->t200_timer = 0;
 -         q921_dchannel_down(pri);
@@ -2765,7 +2858,7 @@
        }
 -	} else if (pri->solicitfbit) {
 +	} else if (pri->solicitfbit[teio]) {
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
+          if (pri->debug & PRI_DEBUG_Q921_DUMP)
              pri_message(pri, "-- Retrying poll with f-bit\n");
 -		pri->retrans++;
 -		if (pri->retrans < pri->timers[PRI_TIMER_N200]) {
@@ -2778,8 +2871,11 @@
 +			q921_rr(pri, 1, 1, tei);
 +			pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
  		} else {
- 			if (pri->debug & PRI_DEBUG_Q921_STATE) 
+ 			if (pri->debug & PRI_DEBUG_Q921_STATE)
  				pri_message(pri, "-- Timeout occured, restarting PRI\n");
+-			if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)
++			if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state[teio] != Q921_LINK_CONNECTION_RELEASED)
+ 				pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n", DBGINFO);
 -			pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
 -			pri->t200_timer = 0;
 -			q921_dchannel_down(pri);
@@ -2797,12 +2893,12 @@
 +		if (pri->busy[teio]) {
 +		    if ((pri->retrans[teio] + 1) <= pri->timers[PRI_TIMER_N200]) {
 +			/* poll RR */
-+    			pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
++ 			pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
 +			pri->retrans[teio]++;
 +			q921_rr(pri, 1, 1, tei);
 +		    } else {
 +			q921_reset(pri, tei, 1);
-+     			q921_start(pri, 1, tei);
++  			q921_start(pri, 1, tei);
 +		    }
 +		}
  	}
@@ -2844,14 +2940,13 @@
 +  	default:
 +  		pri_error(pri, "Don't know how to send U frames on a type %d node\n", pri->localtype);
 +  		return -1;
-+   	}
++	}
 +  	memcpy(uf->data,buf,len);
 +  	q921_transmit(pri, (q921_h*)&(uf->h), 3+len);
 +  	free(uf);
 +  	return 0;
 +}
 +
-+
 +int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr, int tei)
  {
  	q921_frame *f, *prev=NULL;
@@ -2880,11 +2975,11 @@
 +		    pri_message(pri, "Reactivating layer 2\n");
 +	    }
 +	}
-+ 	for (f=pri->txqueue[teio]; f; f = f->next) prev = f;
++	for (f=pri->txqueue[teio]; f; f = f->next) prev = f;
  	f = malloc(sizeof(q921_frame) + len + 2);
  	if (f) {
  		memset(f,0,sizeof(q921_frame) + len + 2);
-@@ -400,47 +973,80 @@
+@@ -406,48 +967,81 @@
  			else
  				f->h.h.c_r = 1;
  		break;
@@ -2913,7 +3008,7 @@
 +  				f->h.h.c_r = 0;
 +  			else
 +  				f->h.h.c_r = 1;
-+  		break;
++   		break;
  		}
  		f->next = NULL;
  		f->transmitted = 0;
@@ -2946,14 +3041,14 @@
 +			pri_message(pri, "Layer 3 transmit waiting for layer 2\n");		
 +		} else {
 +		    /* Immediately transmit unless we're in a recovery state, or the window
-+			size is too big */
++		      size is too big */
 +		    if (!pri->retrans[teio] && !pri->busy[teio]) {
 +			if (pri->windowlen[teio] < pri->window[teio]) {
 +				pri->windowlen[teio]++;
  				q921_transmit(pri, (q921_h *)(&f->h), f->len);
  				f->transmitted++;
  			} else {
- 				if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 				if (pri->debug & PRI_DEBUG_Q921_DUMP)
  					pri_message(pri, "Delaying transmission of %d, window is %d/%d long\n", 
 -						f->h.n_s, pri->windowlen, pri->window);
 +						f->h.n_s, pri->windowlen[teio], pri->window[teio]);
@@ -2964,7 +3059,7 @@
 +		    if (pri->t203_timer[teio]) {
 +			pri_schedule_del(pri, pri->t203_timer[teio]);
 +			pri->t203_timer[teio] = 0;
- 			if (pri->debug & PRI_DEBUG_Q921_STATE)
+ 			if (pri->debug & PRI_DEBUG_Q921_DUMP)
  				pri_message(pri, "Stopping T_203 timer\n");
 -			pri_schedule_del(pri, pri->t203_timer);
 -			pri->t203_timer = 0;
@@ -2972,53 +3067,52 @@
 -		if (!pri->t200_timer) {
 +		    }
 +		    if (!pri->t200_timer[teio]) {
- 			if (pri->debug & PRI_DEBUG_Q921_STATE)
++			pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
+ 			if (pri->debug & PRI_DEBUG_Q921_DUMP)
  				pri_message(pri, "Starting T_200 timer\n");
 -			pri->t200_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
 -		} else
-+			pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-+		    } else
- 			if (pri->debug & PRI_DEBUG_Q921_STATE)
++		    } else {
+ 			if (pri->debug & PRI_DEBUG_Q921_DUMP)
 -				pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer);
+-		
 +				pri_message(pri, "T_200 timer already going (%d)\n", pri->t200_timer[teio]);
++		    }
 +		}
- 		
  	} else {
  		pri_error(pri, "!! Out of memory for Q.921 transmit\n");
-@@ -449,49 +1055,86 @@
+ 		return -1;
+@@ -455,49 +1049,78 @@
  	return 0;
  }
  
 -static void t203_expire(void *vpri)
 +static void t203_expire(void *vpri, int tei)
  {
--	struct pri *pri = vpri;
+ 	struct pri *pri = vpri;
 -	if (pri->q921_state == Q921_LINK_CONNECTION_ESTABLISHED) {
--		if (pri->debug &  PRI_DEBUG_Q921_STATE)
-+  	struct pri *pri = vpri;
 + 	int teio=tei - Q921_TEI_BASE;
 + 	if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+ 
-+ 	if (pri->q921_state[teio] == Q921_LINK_CONNECTION_ESTABLISHED) {
-+  		if (pri->debug &  PRI_DEBUG_Q921_STATE)
++	if (pri->q921_state[teio] == Q921_LINK_CONNECTION_ESTABLISHED) {
+ 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
  			pri_message(pri, "T203 counter expired, sending RR and scheduling T203 again\n");
--		/* Solicit an F-bit in the other's RR */
+ 		/* Solicit an F-bit in the other's RR */
 -		pri->solicitfbit = 1;
 -		pri->retrans = 0;
 -		q921_rr(pri, 1, 1);
--		/* Start timer T200 to resend our RR if we don't get it */
--		pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
-+  		/* Solicit an F-bit in the other's RR */
 +		pri->solicitfbit[teio] = 1;
 +		pri->retrans[teio] = 0;
 +		q921_rr(pri, 1, 1, tei);
-+  		/* Start timer T200 to resend our RR if we don't get it */
+ 		/* Start timer T200 to resend our RR if we don't get it */
+-		pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri);
 +		pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, tei);
-+  	} else {
-+  		if (pri->debug &  PRI_DEBUG_Q921_STATE)
+ 	} else {
+ 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
+-			pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state);
+-		pri->t203_timer = 0;
 +			pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state[teio]);
 +		pri->t203_timer[teio] = 0;
-+  	}
++	}
 +}
 +
 +static void q921_start_tei(struct pri *pri, int tei);
@@ -3033,14 +3127,11 @@
 + 	if (tei == Q921_TEI_GROUP) {
 +	    for (i=0;i<Q921_MAX_TEIS;i++) {
 +		if (pri->q921_tei_check[i] == 1) {
-+		    pri->q921_tei_check[i] = 0;
++ 		    pri->q921_tei_check[i] = 0;
 +		    q921_start_tei(pri, Q921_TEI_BASE + i);
 +		}
-+	    }
- 	} else {
--		if (pri->debug &  PRI_DEBUG_Q921_STATE)
--			pri_message(pri, "T203 counter expired in weird state %d\n", pri->q921_state);
--		pri->t203_timer = 0;
++ 	    }
++	} else {
 +	    if (pri->q921_tei_check[teio] == 1) {
 +		pri->q921_tei_check[teio] = 0;
 +		q921_start_tei(pri, tei);
@@ -3055,7 +3146,6 @@
  	pri_event *ev;
 +	int teio= i->h.tei - Q921_TEI_BASE;
 +	if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
-+//	pri_error(pri, "q921_handle_iframe: i->n_s %d pri->v_r[%d] %d \n", i->n_s, teio, pri->v_r[teio]);
  	/* Make sure this is a valid packet */
 -	if (i->n_s == pri->v_r) {
 +	if (i->n_s == pri->v_r[teio]) {
@@ -3067,22 +3157,15 @@
 -		ev = q921_ack_rx(pri, i->n_r);
 +		pri->sentrej[teio] = 0;
 +		ev = q921_ack_rx(pri, i->n_r, i->h.tei);
-+		if (ev) {
-+		    pri_error(pri, "q921_handle_iframe: ev = %d \n", ev->e);
-+		}
  		if (ev)
  			return ev;
  		if (i->p_f) {
  			/* If the Poll/Final bit is set, immediate send the RR */
 -			q921_rr(pri, 1, 0);
--		} else if (pri->busy) {
--			q921_rr(pri, 0, 0);
 +			q921_rr(pri, 1, 0, i->h.tei);
-+		} else if (pri->busy[teio]) {
+ 		} else if (pri->busy) {
+-			q921_rr(pri, 0, 0);
 +			q921_rr(pri, 0, 0, i->h.tei);
-+		} else if (pri->t200_timer[teio] && pri->retrans[teio]) {
-+		pri_error(pri, "q921_handle_iframe: sending RR \n");
-+			q921_rr(pri, 0, 0, i->h.tei);
  		}
  		/* Receive Q.931 data */
 -		res = q931_receive(pri, (q931_h *)i->data, len - 4);
@@ -3091,11 +3174,11 @@
 -		if (pri->v_na != pri->v_r) 
 -			q921_rr(pri, 0, 0);
 +		if (pri->v_na[teio] != pri->v_r[teio]) 
-+			q921_rr(pri, 0, 0,  i->h.tei);
++			q921_rr(pri, 0, 0, i->h.tei);
  		if (res == -1) {
  			return NULL;
  		}
-@@ -500,10 +1143,10 @@
+@@ -506,10 +1129,10 @@
  	} else {
  		/* If we haven't already sent a reject, send it now, otherwise
  		   we are obliged to RR */
@@ -3109,18 +3192,21 @@
  	}
  	return NULL;
  }
-@@ -641,75 +1284,158 @@
+@@ -647,72 +1270,135 @@
  	};
  }
  
 -static pri_event *q921_dchannel_up(struct pri *pri)
+-{
+-	/* Reset counters, etc */
+-	q921_reset(pri);
 +static void q921_tei_recovery(struct pri *pri, int tei) {
 +    int i = 0;
 +    int teio=tei - Q921_TEI_BASE;
 +    if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
 +    for (i=0;i<Q921_MAX_TEIS;i++) {
-+	if ((i + Q921_TEI_BASE == tei) || (tei == Q921_TEI_GROUP)) {
-+	    pri->q921_tei_check[i] = 1;
++        if ((i + Q921_TEI_BASE == tei) || (tei == Q921_TEI_GROUP)) {
++    	    pri->q921_tei_check[i] = 1;
 +	}
 +    }
 +    q921_send_teichkreq(pri, tei);
@@ -3128,17 +3214,10 @@
 +	pri->t201_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T201], t201_expire, pri, tei);
 +    }
 +}
-+/*
-+static void q921_invoke_tei_recovery(void *vpri, int tei) {
-+  	struct pri *pri = vpri;
-+	q921_tei_recovery(pri, tei);
-+}
-+*/
 +
 +static pri_event *q921_dchannel_up(struct pri *pri, int tei)
- {
--	/* Reset counters, etc */
--	q921_reset(pri);
++{
++//	q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
 + 	// we treat this as MFE
 + 	int teio=tei - Q921_TEI_BASE;
 + 	if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
@@ -3175,12 +3254,17 @@
 +	pri->sentrej[teio] = 0;
  	
  	/* Go into connection established state */
+-	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_ESTABLISHED)
+-		pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_ESTABLISHED\n", DBGINFO);
 -	pri->q921_state = Q921_LINK_CONNECTION_ESTABLISHED;
 -
 -	/* Start the T203 timer */
 -	pri->t203_timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri);
 +	pri->q921_state[teio] = Q921_LINK_CONNECTION_ESTABLISHED;
  	
+-	/* Notify Layer 3 */
+-	q931_dl_indication(pri, PRI_EVENT_DCHAN_UP);
+-
 -	/* Report event that D-Channel is now up */
 -	pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
 -	return &pri->ev;
@@ -3210,6 +3294,9 @@
 +
  	/* Reset counters, reset sabme timer etc */
 -	q921_reset(pri);
+-	
+-	/* Notify Layer 3 */
+-	q931_dl_indication(pri, PRI_EVENT_DCHAN_DOWN);
 + 	if (pri->localtype == BRI_NETWORK_PTMP) {
 + 	    if (pri->t203_timer[teio]) {
 + 		pri_schedule_del(pri, pri->t203_timer[teio]);
@@ -3219,10 +3306,10 @@
 + 		}
 + 	    }
 + 	}
-+
-+	q921_reset(pri, tei, 1);
- 	
+ 
 -	/* Report event that D-Channel is now up */
++	q921_reset(pri, tei, 1);
++	
 + 	/* Report event that D-Channel is now down */
  	pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
 + 	pri->ev.gen.tei = tei;
@@ -3249,6 +3336,8 @@
 -	pri->t200_timer = 0;
 -	pri->busy = 0;
 -	pri->solicitfbit = 0;
+-	if (pri->debug & PRI_DEBUG_Q921_STATE && pri->q921_state != Q921_LINK_CONNECTION_RELEASED)
+-		pri_message(pri, DBGHEAD "q921_state now is Q921_LINK_CONNECTION_RELEASED\n", DBGINFO);
 -	pri->q921_state = Q921_LINK_CONNECTION_RELEASED;
 -	pri->retrans = 0;
 -	pri->sentrej = 0;
@@ -3285,9 +3374,8 @@
 +	}
  }
  
-+
  static pri_event *__q921_receive_qualified(struct pri *pri, q921_h *h, int len)
- {
+@@ -720,12 +1406,16 @@
  	q921_frame *f;
  	pri_event *ev;
  	int sendnow;
@@ -3306,7 +3394,7 @@
  			return NULL;
  		}
  		/* Informational frame */
-@@ -720,8 +1446,10 @@
+@@ -736,8 +1426,10 @@
  		return q921_handle_iframe(pri, &h->i, len);	
  		break;
  	case 1:
@@ -3318,7 +3406,7 @@
  			return NULL;
  		}
  		if (len < 4) {
-@@ -731,80 +1459,128 @@
+@@ -747,56 +1439,75 @@
  		switch(h->s.ss) {
  		case 0:
  			/* Receiver Ready */
@@ -3330,23 +3418,16 @@
  			if (ev)
  				return ev;
  			if (h->s.p_f) {
--				/* If it's a p/f one then send back a RR in return with the p/f bit set */
+ 				/* If it's a p/f one then send back a RR in return with the p/f bit set */
 -				if (pri->solicitfbit) {
-+			/* If it's a p/f one then send back a RR in return with the p/f bit set */
-+//			pri_error(pri, "-- h->s.pf %d pri->solicitfbit[teio] %d\n", h->s.p_f, pri->solicitfbit[teio]);
 +				if (pri->solicitfbit[teio]) {
- 					if (pri->debug & PRI_DEBUG_Q921_STATE) 
+ 					if (pri->debug & PRI_DEBUG_Q921_DUMP)
  						pri_message(pri, "-- Got RR response to our frame\n");
  				} else {
--					if (pri->debug & PRI_DEBUG_Q921_STATE) 
-+					if (pri->txqueue[teio]) {
-+					    q921_flush_txqueue(pri, pri->tei, 0);
-+					} else {
-+					    if (pri->debug & PRI_DEBUG_Q921_STATE) 
+ 					if (pri->debug & PRI_DEBUG_Q921_DUMP)
  						pri_message(pri, "-- Unsolicited RR with P/F bit, responding\n");
 -						q921_rr(pri, 1, 0);
 +						q921_rr(pri, 1, 0, h->h.tei);
-+					}
  				}
 -				pri->solicitfbit = 0;
 +				pri->solicitfbit[teio] = 0;
@@ -3354,7 +3435,7 @@
  			break;
        case 1:
           /* Receiver not ready */
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
+          if (pri->debug & PRI_DEBUG_Q921_DUMP)
              pri_message(pri, "-- Got receiver not ready\n");
 -	 if(h->s.p_f) {
 -		/* Send RR if poll bit set */
@@ -3380,76 +3461,59 @@
 +	    pri->t200_timer[teio] = 0;
  	 }
 -         pri->busy = 1;
--         break;   
 +	 pri->t200_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T200], t200_expire, pri, h->h.tei);
-+         break;
+          break;   
        case 2:
           /* Just retransmit */
-          if (pri->debug & PRI_DEBUG_Q921_STATE)
+          if (pri->debug & PRI_DEBUG_Q921_DUMP)
              pri_message(pri, "-- Got reject requesting packet %d...  Retransmitting.\n", h->s.n_r);
 -         if (h->s.p_f) {
 -            /* If it has the poll bit set, send an appropriate supervisory response */
 -            q921_rr(pri, 1, 0);
 -         }
  		 sendnow = 0;
-+// XXX		 
-+	q921_ack_rx(pri, h->s.n_r, h->h.tei);
++	 q921_ack_rx(pri, h->s.n_r, h->h.tei);
 +         /* Reset t200 timer if it was somehow going */
 +         if (pri->t200_timer[teio]) {
-+               pri_schedule_del(pri, pri->t200_timer[teio]);
-+               pri->t200_timer[teio] = 0;
++            pri_schedule_del(pri, pri->t200_timer[teio]);
++            pri->t200_timer[teio] = 0;
 +         }
++
           /* Resend the proper I-frame */
 -         for(f=pri->txqueue;f;f=f->next) {
 +         for(f=pri->txqueue[teio];f;f=f->next) {
-+//	    pri_error(pri, "!! frame n_s %d transmitted %d (searching for %d)!\n", f->h.n_s, f->transmitted, h->s.n_r);
                 if ((sendnow || (f->h.n_s == h->s.n_r)) && f->transmitted) {
                       /* Matches the request, or follows in our window, and has
  					    already been transmitted. */
--					 sendnow = 1;
--					 pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
+ 					 sendnow = 1;
+ 					 pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
 -				     f->h.n_r = pri->v_r;
--                     q921_transmit(pri, (q921_h *)(&f->h), f->len);
-+
-+		     /* multiframe established */
-+		     f->transmitted = 0;
-+		     f->h.n_r = pri->v_r[teio];
-+		    
-+		    if (pri->busy[teio]) {
-+		      pri->busy[teio] = 0;
-+		      sendnow = 0;
-+		     } else {
-+		        f->h.p_f = 0;
-+		        sendnow = 1;
-+			pri_error(pri, "!! Got reject for frame %d, retransmitting frame %d now, updating n_r!\n", h->s.n_r, f->h.n_s);
-+                        q921_transmit(pri, (q921_h *)(&f->h), f->len);
-+			f->transmitted++;
-+		     }
++				     f->h.n_r = pri->v_r[teio];
+                      q921_transmit(pri, (q921_h *)(&f->h), f->len);
                 }
           }
           if (!sendnow) {
 -               if (pri->txqueue) {
--                     /* This should never happen */
--		     if (!h->s.p_f || h->s.n_r) {
 +               if (pri->txqueue[teio]) {
-+		     if (h->s.p_f) {
-+        		q921_rr(pri, 1, 0, h->h.tei);
-+		     } else if (!h->s.p_f || h->s.n_r) {
+                      /* This should never happen */
+ 		     if (!h->s.p_f || h->s.n_r) {
  			pri_error(pri, "!! Got reject for frame %d, but we only have others!\n", h->s.n_r);
- 		     }
+@@ -804,23 +1515,37 @@
                 } else {
                       /* Hrm, we have nothing to send, but have been REJ'd.  Reset v_a, v_s, etc */
--				pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
+ 				pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
 -                     pri->v_a = h->s.n_r;
 -                     pri->v_s = h->s.n_r;
--                     /* Reset t200 timer if it was somehow going */
++                     pri->v_a[teio] = h->s.n_r;
++                     pri->v_s[teio] = h->s.n_r;
+                      /* Reset t200 timer if it was somehow going */
 -                     if (pri->t200_timer) {
 -                           pri_schedule_del(pri, pri->t200_timer);
 -                           pri->t200_timer = 0;
--                     }
-+/*				pri_error(pri, "!! Got reject for frame %d, but we have nothing -- resetting!\n", h->s.n_r);
-+                     pri->v_a[teio] = h->s.n_r;
-+                     pri->v_s[teio] = h->s.n_r; */
++                     if (pri->t200_timer[teio]) {
++                           pri_schedule_del(pri, pri->t200_timer[teio]);
++                           pri->t200_timer[teio] = 0;
+                      }
                       /* Reset and restart t203 timer */
 -                     if (pri->t203_timer)
 -                           pri_schedule_del(pri, pri->t203_timer);
@@ -3457,24 +3521,22 @@
 +                     if (pri->t203_timer[teio])
 +                           pri_schedule_del(pri, pri->t203_timer[teio]);
 +                     pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, tei);
-+		     pri->solicitfbit[teio] = 0;
                 }
 -         }
-+         } else {
-+    	    if (h->s.p_f) {
++          } else {
++ 	    if (h->s.p_f) {
 +        	/* If it has the poll bit set (and an iframe was retransmitted), send an appropriate supervisory response */
-+//        	q921_rr(pri, 1, 0, h->h.tei);
-+                 /* Reset t200 timer if it was somehow going */
-+                 if (pri->t200_timer[teio]) {
-+                       pri_schedule_del(pri, pri->t200_timer[teio]);
-+                       pri->t200_timer[teio] = 0;
-+                 }
-+                 /* Reset and restart t203 timer */
-+		  pri->solicitfbit[teio] = 0;
-+                 if (pri->t203_timer[teio])
-+                       pri_schedule_del(pri, pri->t203_timer[teio]);
-+                 pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, h->h.tei);
-+            }
++                  /* Reset t200 timer if it was somehow going */
++                  if (pri->t200_timer[teio]) {
++                        pri_schedule_del(pri, pri->t200_timer[teio]);
++                    pri->t200_timer[teio] = 0;
++                  }
++                  /* Reset and restart t203 timer */
++ 		  pri->solicitfbit[teio] = 0;
++                  if (pri->t203_timer[teio])
++                        pri_schedule_del(pri, pri->t203_timer[teio]);
++                  pri->t203_timer[teio] = pri_schedule_event2(pri, pri->timers[PRI_TIMER_T203], t203_expire, pri, h->h.tei);
++             }
 +	 }
           break;
  		default:
@@ -3484,8 +3546,8 @@
  		}
  		break;
  	case 3:
-@@ -821,8 +1597,16 @@
- 					if (pri->debug & PRI_DEBUG_Q921_STATE)
+@@ -837,8 +1562,16 @@
+ 					if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
  						pri_message(pri, "-- Got DM Mode from peer.\n");
  					/* Disconnected mode, try again after T200 */
 -					ev = q921_dchannel_down(pri);
@@ -3503,7 +3565,7 @@
  					return ev;
  						
  				} else {
-@@ -830,21 +1614,153 @@
+@@ -846,21 +1579,153 @@
  						pri_message(pri, "-- Ignoring unsolicited DM with p/f set to 0\n");
  #if 0
  					/* Requesting that we start */
@@ -3513,7 +3575,6 @@
  				}
  				break;
 -			} else if (!h->u.m2) {
--				pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
 +			} else if (h->u.m2 == 0) {
 +				if (h->u.ft == 3) {
 + 				    switch (h->u.data[0]) { /* Management Entity Identifier  */
@@ -3543,7 +3604,7 @@
 + 						    if (pri->debug & PRI_DEBUG_Q921_STATE)
 + 							pri_message(pri, "received TEI assign TEI = %d ri=%d\n",pri->tei,(unsigned short) (h->u.data[1] << 8) + h->u.data[2]);
 +						    pri->sabme_retrans[teio] = 0;
-+     						    q921_send_sabme_now(pri, pri->tei);
++  						    q921_send_sabme_now(pri, pri->tei);
 + 						}
 + 					    break;
 + 					    case Q921_TEI_ID_REMOVE:
@@ -3604,17 +3665,17 @@
 +							// d a t
 +							pri_error(pri, "double assgined tei for tei %d teio %d\n", h->u.data[4] >> 1, teio);
 + 						        pri->q921_tei_check[teio] = 0;
-+     							q921_start_tei(pri, h->u.data[4] >> 1);
++  							q921_start_tei(pri, h->u.data[4] >> 1);
 +						    }
 + 					    break;
 + 					    default:
 + 						pri_message(pri, "Ri = %d TEI msg = %x TEI = %x\n", (h->u.data[1] << 8) + h->u.data[2], h->u.data[3], h->u.data[4] >> 1);
 + 					} 
 + 					break;
-+ 					case Q931_PROTOCOL_DISCRIMINATOR:
++  					case Q931_PROTOCOL_DISCRIMINATOR:
 + 					    if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE)){ 
 + 						res = q931_receive(pri, (q931_h *)h->u.data, len-3, h->h.tei);
-+ 						/* Send an RR if one wasn't sent already */
++  						/* Send an RR if one wasn't sent already */
 + 						if (pri->v_na[teio] != pri->v_r[teio]) 
 + 						    q921_rr(pri, 0, 0, pri->tei);
 + 						if (res == -1) {
@@ -3625,13 +3686,13 @@
 +					    }
 + 					break;
 + 				    }
-+ 				} else {
-+ 				    pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
 +				}
++			} else {
+ 				pri_message(pri, "XXX Unnumbered Information not implemented XXX\n");
  			}
  			break;
  		case 2:
- 			if (pri->debug &  PRI_DEBUG_Q921_STATE)
+ 			if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP))
  				pri_message(pri, "-- Got Disconnect from peer.\n");
 +#ifndef RELAX_TRB
 +			if (pri->q921_state[teio] != Q921_LINK_CONNECTION_ESTABLISHED) {
@@ -3647,7 +3708,7 @@
 +			ev = q921_dchannel_down(pri, h->h.tei);
 +			if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE) || (pri->localtype == BRI_NETWORK)) {
 +#ifndef LAYER2ALWAYSUP
-+    			    /* release layer 2 */
++ 			    /* release layer 2 */
 +			    return NULL;
 +#else
 +			    /* keep layer 2 up */
@@ -3658,12 +3719,12 @@
 +#endif
 + 			}
 + 			if ((pri->localtype == PRI_NETWORK) || (pri->localtype == PRI_CPE)){
-+     			    q921_start(pri, 0, 0);
++  			    q921_start(pri, 0, 0);
 + 			}
  			return ev;
  		case 3:
  			if (h->u.m2 == 3) {
-@@ -866,17 +1782,28 @@
+@@ -882,17 +1747,29 @@
  					}
  				}
  				/* Send Unnumbered Acknowledgement */
@@ -3675,7 +3736,7 @@
  					/* It's a UA */
 -				if (pri->q921_state == Q921_AWAITING_ESTABLISH) {
 +				if (pri->q921_state[teio] == Q921_AWAITING_ESTABLISH) {
- 					if (pri->debug & PRI_DEBUG_Q921_STATE) {
+ 					if (pri->debug & (PRI_DEBUG_Q921_STATE | PRI_DEBUG_Q921_DUMP)) {
  						pri_message(pri, "-- Got UA from %s peer  Link up.\n", h->h.c_r ? "cpe" : "network");
  					}
 -					return q921_dchannel_up(pri);
@@ -3688,38 +3749,44 @@
 +					    q921_reset(pri, h->h.tei, 1);
 +					    q921_send_teiverify(pri, h->h.tei);
 +					} else {
-+					    /* send DM */
-+ 					//    q921_send_dm(pri, 1, h->h.tei);
 +#ifndef RELAX_TRB
 +					    q921_reset(pri, h->h.tei, 1);
++#else
++					    /* send DM */
++ 					    q921_send_dm(pri, 1, h->h.tei);
 +#endif
 +					}
 +				}
  			} else 
  				pri_error(pri, "!! Weird frame received (m3=3, m2 = %d)\n", h->u.m2);
  			break;
-@@ -901,19 +1828,42 @@
+@@ -916,20 +1793,44 @@
+ 	pri_event *ev;
  	/* Discard FCS */
  	len -= 2;
- 	
--	if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)
+-	
+-	if (!pri->master && pri->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
 -		q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
--
+ 
  	/* Check some reject conditions -- Start by rejecting improper ea's */
  	if (h->h.ea1 || !(h->h.ea2))
  		return NULL;
+ 
+-	/* Check for broadcasts - not yet handled */
+-	if (h->h.tei == Q921_TEI_GROUP)
+-		return NULL;
 + 	if ((pri->localtype == PRI_CPE) || (pri->localtype == PRI_NETWORK)) {
 + 	    /* Check for broadcasts - not yet handled (for PRI) */
 + 	    if (h->h.tei == Q921_TEI_GROUP) {
 +  		return NULL;
 + 	    }
 + 	} else if ((pri->localtype == BRI_CPE) || (pri->localtype == BRI_CPE_PTMP)) {
-+     	    if ((h->h.tei != pri->tei) && (h->h.tei != Q921_TEI_GROUP)) {
++  	    if ((h->h.tei != pri->tei) && (h->h.tei != Q921_TEI_GROUP)) {
 + 	    	return NULL;
 + 	    }
 + 	} else if (pri->localtype == BRI_NETWORK_PTMP) {
 + 	    /* discard anything from a strange TEI (strange == not assigned by us or the broadcast tei) */
-+     	    if (((h->h.tei < Q921_TEI_BASE) || (h->h.tei > Q921_TEI_BASE + Q921_MAX_TEIS)) && (h->h.tei != Q921_TEI_GROUP)) {
++  	    if (((h->h.tei < Q921_TEI_BASE) || (h->h.tei > Q921_TEI_BASE + Q921_MAX_TEIS)) && (h->h.tei != Q921_TEI_GROUP)) {
 + 		if (pri->debug & PRI_DEBUG_Q921_DUMP)
 + 		    pri_message(pri, "Received a Q.921 message from strange/unassigned TEI %d.\n");
 + 	    	return NULL;
@@ -3733,22 +3800,19 @@
 + 		}
 + 	    }
 + 	}    
-+  
-+ 	if (!pri->master && pri->debug & PRI_DEBUG_Q921_DUMP)
-+ 		q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
++	
++	if (!pri->master && pri->debug & (PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW))
++		q921_dump(pri, h, len, pri->debug & PRI_DEBUG_Q921_RAW, 0);
  
--	/* Check for broadcasts - not yet handled */
--	if (h->h.tei == Q921_TEI_GROUP)
--		return NULL;
- 
-+ 	if (pri->localtype != BRI_NETWORK_PTMP) {
  	/* Check for SAPIs we don't yet handle */
 -	if ((h->h.sapi != pri->sapi) || (h->h.tei != pri->tei)) {
++ 	if (pri->localtype != BRI_NETWORK_PTMP) {
++  	/* Check for SAPIs we don't yet handle */
 +	    if (((h->h.sapi != pri->sapi) && (h->h.sapi != Q921_SAPI_LAYER2_MANAGEMENT)) || ((h->h.tei != pri->tei) && (h->h.tei != Q921_TEI_GROUP) )) {
  #ifdef PROCESS_SUBCHANNELS
  		/* If it's not us, try any subchannels we have */
  		if (pri->subchannel)
-@@ -921,10 +1871,16 @@
+@@ -937,10 +1838,16 @@
  		else 
  #endif
  			return NULL;
@@ -3767,7 +3831,7 @@
  	return ev;
  }
  
-@@ -938,14 +1894,58 @@
+@@ -954,14 +1861,58 @@
  	return e;
  }
  
@@ -3834,9 +3898,9 @@
 -	/* Do the SABME XXX Maybe we should implement T_WAIT? XXX */
 -	q921_send_sabme(pri, now);
  }
-diff -urN libpri-1.2.4.orig/q931.c libpri-1.2.4/q931.c
---- libpri-1.2.4.orig/q931.c	2006-07-28 16:44:15.000000000 +0200
-+++ libpri-1.2.4/q931.c	2006-10-19 11:08:07.000000000 +0200
+diff -urN libpri-1.4.1.orig/q931.c libpri-1.4.1/q931.c
+--- libpri-1.4.1.orig/q931.c	2007-06-19 20:23:36.000000000 +0200
++++ libpri-1.4.1/q931.c	2007-07-11 14:25:15.000000000 +0200
 @@ -1,10 +1,12 @@
  /*
   * libpri: An implementation of Primary Rate ISDN
@@ -3867,9 +3931,9 @@
  #include <stdlib.h>
 +#include <time.h>
  #include <string.h>
+ #include <ctype.h>
  #include <stdio.h>
- #include <limits.h>
-@@ -205,6 +208,14 @@
+@@ -208,6 +211,14 @@
  #define LOC_INTERNATIONAL_NETWORK	0x7
  #define LOC_NETWORK_BEYOND_INTERWORKING	0xa
  
@@ -3884,7 +3948,7 @@
  static char *ie2str(int ie);
  static char *msg2str(int msg);
  
-@@ -241,6 +252,7 @@
+@@ -256,6 +267,7 @@
  static void call_init(struct q931_call *c)
  {
  	memset(c, 0, sizeof(*c));
@@ -3892,7 +3956,7 @@
  	c->alive = 0;
  	c->sendhangupack = 0;
  	c->forceinvert = -1;	
-@@ -253,8 +265,16 @@
+@@ -268,8 +280,16 @@
  	c->next = NULL;
  	c->sentchannel = 0;
  	c->newcall = 1;
@@ -3909,7 +3973,7 @@
  }
  
  static char *binary(int b, int len) {
-@@ -272,14 +292,17 @@
+@@ -287,14 +307,17 @@
  {	
  	int x;
  	int pos=0;
@@ -3933,7 +3997,7 @@
  		case 0:
  			call->justsignalling = 1;
  			break;
-@@ -288,6 +311,7 @@
+@@ -303,6 +326,7 @@
  		default:
  			pri_error(pri, "!! Unexpected Channel selection %d\n", ie->data[0] & 3);
  			return -1;
@@ -3941,7 +4005,7 @@
  	}
  #endif
  	if (ie->data[0] & 0x08)
-@@ -349,10 +373,16 @@
+@@ -364,10 +388,16 @@
  	}
  		
  	/* Start with standard stuff */
@@ -3960,7 +4024,7 @@
  	/* Add exclusive flag if necessary */
  	if (call->chanflags & FLAG_EXCLUSIVE)
  		ie->data[pos] |= 0x08;
-@@ -369,6 +399,7 @@
+@@ -384,6 +414,7 @@
  	} else
  		pos++;
  	if ((call->channelno > -1) || (call->slotmap != -1)) {
@@ -3968,7 +4032,7 @@
  		/* We'll have the octet 8.2 and 8.3's present */
  		ie->data[pos++] = 0x83;
  		if (call->channelno > -1) {
-@@ -384,11 +415,43 @@
+@@ -399,11 +430,43 @@
  			ie->data[pos++] = (call->slotmap & 0xff);
  			return pos + 2;
  		}
@@ -4013,7 +4077,7 @@
  	pri_error(pri, "!! No channel map, no channel, and no ds1?  What am I supposed to identify?\n");
  	return -1;
  }
-@@ -734,9 +797,13 @@
+@@ -749,9 +812,13 @@
  	return code2str(pres, press, sizeof(press) / sizeof(press[0]));
  }
  
@@ -4029,102 +4093,43 @@
  		num[0] = 0;
  		return;
  	}
-@@ -746,50 +813,75 @@
+@@ -761,7 +828,7 @@
  
  static FUNC_DUMP(dump_called_party_number)
  {
 -	unsigned char cnum[256];
--
--	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--	pri_message(pri, "%c Called Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d) '%s' ]\n",
--		prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f, cnum);
 +	char cnum[256];
-+ 	if (len >= 3) {
-+ 	    q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+	    pri_message(pri, "%c Called Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d) '%s' ]\n",
-+ 		    prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f, cnum);
-+ 	} else {
-+ 	    pri_error(pri, "Called Number (len=%2d) too short.\n", len);
-+ 	}
- }
  
+ 	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
+ 	pri_message(pri, "%c Called Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)  '%s' ]\n",
+@@ -770,7 +837,7 @@
+ 
  static FUNC_DUMP(dump_called_party_subaddr)
  {
 -	unsigned char cnum[256];
--	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--	pri_message(pri, "%c Called Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
--		prefix, len, ie->data[0] >> 7,
--		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
--		(ie->data[0] & 0x08) >> 3, cnum);
 +	char cnum[256];
-+ 	if (len >= 3) {
-+ 	    q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+ 	    pri_message(pri, "%c Called Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
-+  		prefix, len, ie->data[0] >> 7,
-+  		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-+  		(ie->data[0] & 0x08) >> 3, cnum);
-+ 	} else {
-+ 	    pri_error(pri, "Called Party Subaddress (len=%2d) too short.\n", len);
-+ 	}
- }
+ 	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
+ 	pri_message(pri, "%c Called Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",
+ 		prefix, len, ie->data[0] >> 7,
+@@ -780,7 +847,7 @@
  
  static FUNC_DUMP(dump_calling_party_number)
  {
 -	unsigned char cnum[256];
--	if (ie->data[0] & 0x80)
--		q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--	else
--		q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
--	pri_message(pri, "%c Calling Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
--	if (ie->data[0] & 0x80)
--		pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(0), 0, cnum);
--	else
--		pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, cnum);
-+  	char cnum[256];
-+ 	if ((ie->data[0] & 0x80) && (len >= 3)) {
-+  		q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+ 		pri_message(pri, "%c Calling Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
-+  		pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(0), 0, cnum);
-+ 	} else if (len >= 4) {
-+ 		q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
-+ 		pri_message(pri, "%c Calling Number (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
-+  		pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, cnum);
-+ 	} else {
-+ 	    pri_error(pri, "Calling Party Number (len=%2d) too short.\n", len);
-+ 	}
- }
++	char cnum[256];
+ 	if (ie->data[0] & 0x80)
+ 		q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
+ 	else
+@@ -794,7 +861,7 @@
  
  static FUNC_DUMP(dump_calling_party_subaddr)
  {
 -	unsigned char cnum[256];
--	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
--	pri_message(pri, "%c Calling Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
--		prefix, len, ie->data[0] >> 7,
--		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
--		(ie->data[0] & 0x08) >> 3, cnum);
 +	char cnum[256];
-+ 	if (len >= 4) {
-+ 	    q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-+ 	    pri_message(pri, "%c Calling Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
-+  		prefix, len, ie->data[0] >> 7,
-+  		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-+  		(ie->data[0] & 0x08) >> 3, cnum);
-+ 	} else {
-+ 	    pri_error(pri, "Calling Party Subaddress (len=%2d) too short.\n", len);
-+ 	}
-+}
-+
-+static FUNC_DUMP(dump_colp)
-+{
-+ 	char cnum[256];
-+ 	if (len >= 4) {
-+ 	    q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
-+ 	    pri_message(pri, "%c COLP (len=%2d) [ Ext: %d  TON: %s (%d)  NPI: %s (%d)\n", prefix, len, ie->data[0] >> 7, ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07, npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
-+ 	    pri_message(pri, "%c                           Presentation: %s (%d) '%s' ]\n", prefix, pri_pres2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f, cnum);
-+ 	} else {
-+ 	    pri_error(pri, "COLP (len=%2d) too short.\n", len);
-+ 	}
- }
+ 	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
+ 	pri_message(pri, "%c Calling Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",
+ 		prefix, len, ie->data[0] >> 7,
+@@ -804,7 +871,7 @@
  
  static FUNC_DUMP(dump_redirecting_number)
  {
@@ -4133,19 +4138,7 @@
  	int i = 0;
  	/* To follow Q.931 (4.5.1), we must search for start of octet 4 by
  	   walking through all bytes until one with ext bit (8) set to 1 */
-@@ -810,13 +902,17 @@
- 		}
- 	}
- 	while(!(ie->data[i++]& 0x80));
--	q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
--	pri_message(pri, " '%s' ]\n", cnum);
-+	if ((ie->len - i) >= 0) {
-+	    q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
-+	    pri_message(pri, " '%s' ]\n", cnum);
-+	} else {
-+	    pri_error(pri, "Redirecting Number (len=%2d) too short.\n", len);
-+	}
- }
+@@ -831,7 +898,7 @@
  
  static FUNC_DUMP(dump_connected_number)
  {
@@ -4154,31 +4147,16 @@
  	int i = 0;
  	/* To follow Q.931 (4.5.1), we must search for start of octet 4 by
  	   walking through all bytes until one with ext bit (8) set to 1 */
-@@ -833,8 +929,12 @@
+@@ -873,7 +940,7 @@
  		}
  	}
- 	while(!(ie->data[i++]& 0x80));
--	q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
--	pri_message(pri, " '%s' ]\n", cnum);
-+	if ((ie->len - i) >= 0) {
-+	    q931_get_number(cnum, sizeof(cnum), ie->data + i, ie->len - i);
-+	    pri_message(pri, " '%s' ]\n", cnum);
-+	} else {
-+	    pri_error(pri, "Connected Number (len=%2d) too short.\n", len);
-+	}
- }
- 
- 
-@@ -858,7 +958,7 @@
- 		}
- 	}
  	while(!(ie->data[i++] & 0x80));
 -	q931_get_number((unsigned char *) call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i);
 +	q931_get_number(call->redirectingnum, sizeof(call->redirectingnum), ie->data + i, ie->len - i);
  	return 0;
  }
  
-@@ -866,7 +966,7 @@
+@@ -881,7 +948,7 @@
  {
  	if (order > 1)
  		return 0;
@@ -4187,136 +4165,51 @@
  		ie->data[0] = call->redirectingplan;
  		ie->data[1] = call->redirectingpres;
  		ie->data[2] = (call->redirectingreason & 0x0f) | 0x80;
-@@ -878,67 +978,90 @@
+@@ -893,7 +960,7 @@
  
  static FUNC_DUMP(dump_redirecting_subaddr)
  {
 -	unsigned char cnum[256];
--	q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
--	pri_message(pri, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
--		prefix, len, ie->data[0] >> 7,
--		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
--		(ie->data[0] & 0x08) >> 3, cnum);
 +	char cnum[256];
-+ 	if (len >= 4) {
-+ 	    q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
-+ 	    pri_message(pri, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d) O: %d '%s' ]\n",
-+  		prefix, len, ie->data[0] >> 7,
-+  		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-+  		(ie->data[0] & 0x08) >> 3, cnum);
-+ 	} else {
-+ 	    pri_error(pri, "Redirecting Subaddress (len=%2d) too short.\n", len);
-+ 	}
- }
- 
+ 	q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
+ 	pri_message(pri, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",
+ 		prefix, len, ie->data[0] >> 7,
+@@ -904,14 +971,14 @@
  static FUNC_RECV(receive_calling_party_subaddr)
  {
  	/* copy digits to call->callingsubaddr */
 - 	q931_get_number((unsigned char *) call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);
-+ 	if (len >= 4) {
-+  	    q931_get_number(call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);
-+ 	} else {
-+	    pri_error(call->pri, "Calling Party Subaddress (len=%2d) too short.\n", len);
-+ 	}
++ 	q931_get_number(call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);
  	return 0;
  }
  
  static FUNC_RECV(receive_called_party_number)
  {
--	/* copy digits to call->callednum */
+ 	/* copy digits to call->callednum */
 - 	q931_get_number((unsigned char *) call->callednum, sizeof(call->callednum), ie->data + 1, len - 3);
--	call->calledplan = ie->data[0] & 0x7f;
-+ 	/* copy digits to call->callednum or call->digits */
-+ 	if (len >= 3) {
-+ 	    if (msgtype == Q931_INFORMATION) {
-+  		q931_get_number(call->digits, sizeof(call->digits), ie->data + 1, len - 3);
-+ 	    } else {
-+  		q931_get_number(call->callednum, sizeof(call->callednum), ie->data + 1, len - 3);
-+ 	    }
-+ 	    call->calledplan = ie->data[0] & 0x7f;
-+ 	} else {
-+ 	    pri_error(call->pri, "Called Party Number (len=%2d) too short.\n", len);
-+ 	}
++ 	q931_get_number(call->callednum, sizeof(call->callednum), ie->data + 1, len - 3);
+ 	call->calledplan = ie->data[0] & 0x7f;
  	return 0;
  }
+@@ -941,7 +1008,7 @@
  
- static FUNC_SEND(transmit_called_party_number)
- {
- 	ie->data[0] = 0x80 | call->calledplan;
--	if (*call->callednum)
-+	if (strlen(call->callednum)) 
- 		memcpy(ie->data + 1, call->callednum, strlen(call->callednum));
- 	return strlen(call->callednum) + 3;
- }
- 
- static FUNC_RECV(receive_calling_party_number)
- {
--	u_int8_t *data;
--	size_t length;
--        
--	if (ie->data[0] & 0x80) {
--		data = ie->data + 1;
--		length = len - 3;
--		call->callerpres = 0; /* PI presentation allowed SI user-provided, not screened */        
--	} else {
--		data = ie->data + 2;
--		length = len - 4;
--		call->callerpres = ie->data[1] & 0x7f;
--	}
--
--	if (call->callerpres == PRES_ALLOWED_NETWORK_NUMBER ||
--		call->callerpres == PRES_PROHIB_NETWORK_NUMBER) {
+ 	if (call->callerpres == PRES_ALLOWED_NETWORK_NUMBER ||
+ 		call->callerpres == PRES_PROHIB_NETWORK_NUMBER) {
 -		q931_get_number((u_int8_t *)call->callerani, sizeof(call->callerani), data, length);
--		call->callerplanani = ie->data[0] & 0x7f;
--
--		if (!*call->callernum) { /*Copy ANI to CallerID if CallerID is not already set */
--			libpri_copy_string(call->callernum, call->callerani, sizeof(call->callernum));
--			call->callerplan = call->callerplanani;
--		}
--		
--	} else {
++		q931_get_number((char *)call->callerani, sizeof(call->callerani), data, length);
+ 		call->callerplanani = ie->data[0] & 0x7f;
+ 
+ 		if (!*call->callernum) { /*Copy ANI to CallerID if CallerID is not already set */
+@@ -950,7 +1017,7 @@
+ 		}
+ 		
+ 	} else {
 -		q931_get_number((u_int8_t *)call->callernum, sizeof(call->callernum), data, length);
--		call->callerplan = ie->data[0] & 0x7f;
--	}
-+/// callerani!!
-+ 	if (strlen(call->callernum)) {
-+     	    call->callerplanuser = ie->data[0] & 0x7f;
-+ 	} else {
-+     	    call->callerplan = ie->data[0] & 0x7f;
-+ 	}
++		q931_get_number((char *)call->callernum, sizeof(call->callernum), data, length);
+ 		call->callerplan = ie->data[0] & 0x7f;
+ 	}
  
-+        if (ie->data[0] & 0x80) {
-+ 	  if (len >= 3) {
-+ 	     if (strlen(call->callernum)) {
-+ 		// got A NUM already (this is not 100% correct, but the network should do it this way to protect bad implementations
-+ 		 q931_get_number(call->callerani, sizeof(call->callerani), ie->data + 1, len - 3);
-+ 	        call->callerpresuser = 0; /* PI presentation allowed
-+ 				   SI user-provided, not screened */        
-+ 	    } else {
-+ 		 q931_get_number(call->callernum, sizeof(call->callernum), ie->data + 1, len - 3);
-+ 		 call->callerpres = 0; /* PI presentation allowed
-+  				   SI user-provided, not screened */        
-+ 	    }
-+ 	  } else {
-+ 		pri_error(call->pri, "Calling Party Number (len=%2d) too short.\n", len);
-+ 	  }
-+        } else {
-+ 	  if (len >= 4) {
-+ 	     if (strlen(call->callernum)) {
-+ 	        q931_get_number(call->callerani, sizeof(call->callerani), ie->data + 2, len - 4);
-+ 		 call->callerpresuser = ie->data[1] & 0x7f;
-+ 	      } else {
-+ 		 q931_get_number(call->callernum, sizeof(call->callernum), ie->data + 2, len - 4);
-+ 	         call->callerpres = ie->data[1] & 0x7f;
-+ 	    }
-+ 	  } else {
-+ 		pri_error(call->pri, "Calling Party Number (len=%2d) too short.\n", len);
-+ 	  }
-+        }
- 	return 0;
- }
- 
-@@ -946,7 +1069,7 @@
+@@ -961,7 +1028,7 @@
  {
  	ie->data[0] = call->callerplan;
  	ie->data[1] = 0x80 | call->callerpres;
@@ -4325,7 +4218,7 @@
  		memcpy(ie->data + 2, call->callernum, strlen(call->callernum));
  	return strlen(call->callernum) + 4;
  }
-@@ -964,11 +1087,89 @@
+@@ -979,11 +1046,89 @@
  static FUNC_RECV(receive_user_user)
  {        
          call->useruserprotocoldisc = ie->data[0] & 0xff;
@@ -4417,56 +4310,18 @@
  static FUNC_SEND(transmit_user_user)
  {        
  	int datalen = strlen(call->useruserinfo);
-@@ -1050,22 +1251,41 @@
+@@ -1065,7 +1210,7 @@
  		data++;
  		len--;
  	}
 -	q931_get_number((unsigned char *) call->callername, sizeof(call->callername), data, len - 2);
-+ 	if (msgtype == Q931_SETUP) {
-+ 	    /* we treat display IEs in the SETUP msg as callername */
-+ 	    if (len >= 2) {
-+ 		q931_get_number(call->callername, sizeof(call->callername), data, len - 2);
-+ 	    } else {
-+ 		pri_error(call->pri, "Display (len=%2d) too short.\n", len);
-+ 	    }
-+ 	} else {
-+ 	    /* in other msgs we will pass it as text to chan_zap */
-+ 	    if (len >= 2) {
-+ 		q931_get_number(call->display, sizeof(call->display), data, len - 2);
-+ 	    } else {
-+ 		pri_error(call->pri, "Display (len=%2d) too short.\n", len);
-+ 	    }
-+ 	}
++	q931_get_number((char *) call->callername, sizeof(call->callername), data, len - 2);
  	return 0;
  }
  
- static FUNC_SEND(transmit_display)
- {
- 	int i;
--	if ((pri->switchtype != PRI_SWITCH_NI1) && (pri->switchtype != PRI_SWITCH_QSIG) 
--			&& *call->callername) {
-+	int cpe = pri->localtype == BRI_CPE || pri->localtype == BRI_CPE_PTMP || pri->localtype == PRI_CPE;
-+ 	if ((pri->switchtype != PRI_SWITCH_NI1) && (pri->switchtype != PRI_SWITCH_QSIG) && strlen(call->callername) && !cpe) {
- 		i = 0;
- 		if(pri->switchtype != PRI_SWITCH_EUROISDN_E1) {
- 			ie->data[0] = 0xb1;
- 			++i;
- 		}
--		memcpy(ie->data + i, call->callername, strlen(call->callername));
--		return 2 + i + strlen(call->callername);
-+ 	    	if (msgtype == Q931_SETUP_ACKNOWLEDGE) {
-+ 		    memcpy(ie->data + i, call->display, strlen(call->display));
-+ 		    return 2 + i + strlen(call->display);
-+ 	 	} else {
-+ 		    memcpy(ie->data + i, call->callername, strlen(call->callername));
-+ 		    return 2 + i + strlen(call->callername);
-+ 	    	}
- 	}
+@@ -1129,6 +1274,111 @@
  	return 0;
  }
-@@ -1112,6 +1332,111 @@
- 	return 0;
- }
  
 + #if 0
 +  static FUNC_RECV(receive_facility_kpj)
@@ -4576,7 +4431,7 @@
  static FUNC_SEND(transmit_facility)
  {
  	struct apdu_event *tmp;
-@@ -1138,6 +1463,182 @@
+@@ -1154,6 +1404,182 @@
  	return i + 2;
  }
  
@@ -4759,15 +4614,33 @@
  static FUNC_RECV(receive_facility)
  {
  	int i = 0;
-@@ -1346,6 +1847,7 @@
+@@ -1361,6 +1787,25 @@
  	pri_message(pri, " ]\n");
  }
  
 +
++static FUNC_RECV(receive_time_date)
++{
++	return 0;
++}
++
++static FUNC_SEND(transmit_time_date) {
++	time_t now;
++	struct tm *timedate;
++	time(&now);
++	timedate = localtime(&now);
++	ie->data[0] = timedate->tm_year - 100; // 1900+
++	ie->data[1] = timedate->tm_mon + 1;
++	ie->data[2] = timedate->tm_mday;
++	ie->data[3] = timedate->tm_hour;
++	ie->data[4] = timedate->tm_min;
++	return 7;
++}
++
  static FUNC_DUMP(dump_time_date)
  {
  	pri_message(pri, "%c Time Date (len=%2d) [ ", prefix, len);
-@@ -1366,7 +1868,7 @@
+@@ -1381,7 +1826,7 @@
  
  static FUNC_DUMP(dump_keypad_facility)
  {
@@ -4776,116 +4649,7 @@
  	
  	if (ie->len == 0 || ie->len > sizeof(tmp))
  		return;
-@@ -1377,28 +1879,49 @@
- 
- static FUNC_RECV(receive_keypad_facility)
- {
--	int mylen;
-+	int mylen = 0;
- 
- 	if (ie->len == 0)
- 		return -1;
- 
- 	if (ie->len > (sizeof(call->digitbuf) - 1))
--		mylen = (sizeof(call->digitbuf) - 1);
-+		mylen = sizeof(call->digitbuf) - 1;
- 	else
- 		mylen = ie->len;
- 
--	memcpy(call->digitbuf, ie->data, mylen);
-+	strncpy(call->digitbuf, (char *) ie->data, mylen);
- 
--	call->digitbuf[mylen] = 0;
-+	/* I must be really neurotic */
-+	call->digitbuf[sizeof(call->digitbuf)-1] = '\0';
- 
- 	return 0;
- }
- 
-+static FUNC_RECV(receive_time_date)
-+{
-+    return 0;
-+}
-+
-+static FUNC_SEND(transmit_time_date) {
-+    time_t now;
-+    struct tm *timedate;
-+    time(&now);
-+    timedate = localtime(&now);
-+    ie->data[0] = timedate->tm_year - 100; // 1900+
-+    ie->data[1] = timedate->tm_mon + 1;
-+    ie->data[2] = timedate->tm_mday;
-+    ie->data[3] = timedate->tm_hour;
-+    ie->data[4] = timedate->tm_min;
-+    return 7;
-+}
-+
-+
-+
- static FUNC_DUMP(dump_display)
- {
- 	int x, y;
- 	char *buf = malloc(len + 1);
--	char tmp[80] = "";
-+	char tmp[80]="";
- 	if (buf) {
- 		x=y=0;
- 		if ((x < ie->len) && (ie->data[x] & 0x80)) {
-@@ -1413,7 +1936,7 @@
- 	}
- }
- 
--static void dump_ie_data(unsigned char *c, int len)
-+static void dump_ie_data(struct pri *pri, unsigned char *c, int len)
- {
- 	char tmp[1024] = "";
- 	int x=0;
-@@ -1423,7 +1946,7 @@
- 		    ((*c >= 'a') && (*c <= 'z')) ||
- 		    ((*c >= '0') && (*c <= '9'))) {
- 			if (!lastascii) {
--				if (*tmp) { 
-+				if (strlen(tmp)) { 
- 					tmp[x++] = ',';
- 					tmp[x++] = ' ';
- 				}
-@@ -1435,7 +1958,7 @@
- 			if (lastascii) {
- 				tmp[x++] = '\'';
- 			}
--			if (*tmp) { 
-+			if (strlen(tmp)) { 
- 				tmp[x++] = ',';
- 				tmp[x++] = ' ';
- 			}
-@@ -1448,14 +1971,14 @@
- 	}
- 	if (lastascii)
- 		tmp[x++] = '\'';
--	pri_message(NULL, tmp);
-+	pri_message(pri, tmp);
- }
- 
- static FUNC_DUMP(dump_facility)
- {
- 	pri_message(pri, "%c Facility (len=%2d, codeset=%d) [ ", prefix, len, Q931_IE_CODESET(full_ie));
--	dump_ie_data(ie->data, ie->len);
--	pri_message(NULL, " ]\n");
-+	dump_ie_data(pri, ie->data, ie->len);
-+	pri_message(pri, " ]\n");
- }
- 
- static FUNC_DUMP(dump_network_spec_fac)
-@@ -1465,7 +1988,7 @@
- 		pri_message(pri, code2str(ie->data[1], facilities, sizeof(facilities) / sizeof(facilities[0])));
- 	}
- 	else
--		dump_ie_data(ie->data, ie->len);
-+		dump_ie_data(pri, ie->data, ie->len);
- 	pri_message(pri, " ]\n");
- }
- 
-@@ -1932,8 +2455,8 @@
+@@ -1991,8 +2436,8 @@
  	{ 1, Q931_REDIRECTING_SUBADDR, "Redirecting Subaddress", dump_redirecting_subaddr },
  	{ 0, Q931_TRANSIT_NET_SELECT, "Transit Network Selection" },
  	{ 1, Q931_RESTART_INDICATOR, "Restart Indicator", dump_restart_indicator, receive_restart_indicator, transmit_restart_indicator },
@@ -4894,9 +4658,9 @@
 +	{ 0, Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" , dump_low_layer_compat, receive_low_layer_compat, transmit_low_layer_compat },
 +	{ 1, Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" , dump_high_layer_compat, receive_high_layer_compat, transmit_high_layer_compat },
  	{ 1, Q931_PACKET_SIZE, "Packet Size" },
- 	{ 1, Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility },
+ 	{ 0, Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility },
  	{ 1, Q931_IE_REDIRECTION_NUMBER, "Redirection Number" },
-@@ -1942,11 +2465,11 @@
+@@ -2001,11 +2446,11 @@
  	{ 1, Q931_IE_INFO_REQUEST, "Feature Request" },
  	{ 1, Q931_IE_FEATURE_IND, "Feature Indication" },
  	{ 1, Q931_IE_SEGMENTED_MSG, "Segmented Message" },
@@ -4906,19 +4670,19 @@
  	{ 1, Q931_IE_NOTIFY_IND, "Notification Indicator", dump_notify, receive_notify, transmit_notify },
  	{ 1, Q931_DISPLAY, "Display", dump_display, receive_display, transmit_display },
 -	{ 1, Q931_IE_TIME_DATE, "Date/Time", dump_time_date },
-+ 	{ 1, Q931_IE_TIME_DATE, "Date/Time", dump_time_date, receive_time_date, transmit_time_date },
- 	{ 1, Q931_IE_KEYPAD_FACILITY, "Keypad Facility", dump_keypad_facility, receive_keypad_facility },
++	{ 1, Q931_IE_TIME_DATE, "Date/Time", dump_time_date, receive_time_date, transmit_time_date },
+ 	{ 1, Q931_IE_KEYPAD_FACILITY, "Keypad Facility", dump_keypad_facility, receive_keypad_facility, transmit_keypad_facility },
  	{ 0, Q931_IE_SIGNAL, "Signal", dump_signal },
  	{ 1, Q931_IE_SWITCHHOOK, "Switch-hook" },
-@@ -1954,6 +2477,7 @@
+@@ -2013,6 +2458,7 @@
  	{ 1, Q931_IE_ESCAPE_FOR_EXT, "Escape for Extension" },
  	{ 1, Q931_IE_CALL_STATUS, "Call Status" },
  	{ 1, Q931_IE_CHANGE_STATUS, "Change Status" },
-+	{ 1, Q931_COLP, "Connect Line ID Presentation", dump_colp},
++	{ 1, Q931_COLP, "Connect Line ID Presentation", dump_connected_number},
  	{ 1, Q931_IE_CONNECTED_ADDR, "Connected Number", dump_connected_number },
  	{ 1, Q931_IE_CONNECTED_NUM, "Connected Number", dump_connected_number },
  	{ 1, Q931_IE_ORIGINAL_CALLED_NUMBER, "Original Called Number", dump_redirecting_number, receive_redirecting_number, transmit_redirecting_number },
-@@ -2024,7 +2548,7 @@
+@@ -2085,7 +2531,7 @@
  {
  	if ((ie->ie & 0x80) != 0)
  		return 1;
@@ -4927,7 +4691,7 @@
  		return 2 + ie->len;
  }
  
-@@ -2054,10 +2578,10 @@
+@@ -2115,10 +2561,10 @@
  			break;
  		case 1:
  			cr = h->crv[0];
@@ -4940,8 +4704,8 @@
  			break;
  		default:
  			pri_error(NULL, "Call Reference Length not supported: %d\n", h->crlen);
-@@ -2100,14 +2624,46 @@
- 	pri_error(pri, "!! %c Unknown IE %d (len = %d)\n", prefix, base_ie, ielen(ie));
+@@ -2161,14 +2607,46 @@
+ 	pri_error(pri, "!! %c Unknown IE %d (cs%d, len = %d)\n", prefix, Q931_IE_IE(base_ie), Q931_IE_CODESET(base_ie), ielen(ie));
  }
  
 -static q931_call *q931_getcall(struct pri *pri, int cr)
@@ -4990,7 +4754,7 @@
  		prev = cur;
  		cur = cur->next;
  	}
-@@ -2120,6 +2676,7 @@
+@@ -2181,6 +2659,7 @@
  		/* Call reference */
  		cur->cr = cr;
  		cur->pri = pri;
@@ -4998,7 +4762,7 @@
  		/* Append to end of list */
  		if (prev)
  			prev->next = cur;
-@@ -2135,24 +2692,42 @@
+@@ -2196,24 +2675,42 @@
  	do {
  		cur = *pri->callpool;
  		pri->cref++;
@@ -5048,7 +4812,7 @@
  			if (prev)
  				prev->next = cur->next;
  			else
-@@ -2161,6 +2736,8 @@
+@@ -2222,6 +2719,8 @@
  				pri_message(pri, "NEW_HANGUP DEBUG: Destroying the call, ourstate %s, peerstate %s\n",callstate2str(cur->ourcallstate),callstate2str(cur->peercallstate));
  			if (cur->retranstimer)
  				pri_schedule_del(pri, cur->retranstimer);
@@ -5057,7 +4821,7 @@
  			pri_call_apdu_queue_cleanup(cur);
  			free(cur);
  			return;
-@@ -2171,16 +2748,16 @@
+@@ -2232,16 +2731,16 @@
  	pri_error(pri, "Can't destroy call %d!\n", cr);
  }
  
@@ -5077,7 +4841,7 @@
  	return;
  }
  
-@@ -2292,6 +2869,10 @@
+@@ -2353,6 +2852,10 @@
  {
  	unsigned int x;
  	int full_ie = Q931_FULL_IE(codeset, ie->ie);
@@ -5088,7 +4852,7 @@
  	if (pri->debug & PRI_DEBUG_Q931_STATE)
  		pri_message(pri, "-- Processing IE %d (cs%d, %s)\n", ie->ie, codeset, ie2str(full_ie));
  	for (x=0;x<sizeof(ies) / sizeof(ies[0]);x++) {
-@@ -2309,21 +2890,36 @@
+@@ -2370,21 +2873,36 @@
  	return -1;
  }
  
@@ -5130,7 +4894,7 @@
  	}
  	if (pri->subchannel) {
  		/* On GR-303, top bit is always 0 */
-@@ -2332,13 +2928,23 @@
+@@ -2393,13 +2911,23 @@
  	mh->f = 0;
  	*hb = h;
  	*mhb = mh;
@@ -5158,7 +4922,7 @@
  	/* The transmit operation might dump the q921 header, so logging the q931
  	   message body after the transmit puts the sections of the message in the
  	   right order in the log */
-@@ -2364,7 +2970,11 @@
+@@ -2424,7 +2952,11 @@
  	
  	memset(buf, 0, sizeof(buf));
  	len = sizeof(buf);
@@ -5171,7 +4935,7 @@
  	mh->msg = msgtype;
  	x=0;
  	codeset = 0;
-@@ -2399,11 +3009,34 @@
+@@ -2442,7 +2974,11 @@
  	}
  	/* Invert the logic */
  	len = sizeof(buf) - len;
@@ -5184,31 +4948,8 @@
  	c->acked = 1;
  	return 0;
  }
- 
-+static int facility_ies[] = { Q931_IE_FACILITY, -1 };
-+
-+#if 0
-+int q931_facility_kpj(struct pri *pri, q931_call *c, int operation, char *arguments)
-+{
-+	switch (operation) {
-+	    case 0x26:	c->aoc = 1;
-+			break;
-+	    case 0x24:	c->aoc = 1;
-+			break;
-+	    case 0x22:	c->aoc = 1;
-+			break;
-+	    default:
-+		return -1;
-+	}
-+	return send_message(pri, c, Q931_FACILITY, facility_ies);
-+}
-+#endif
-+
- static int status_ies[] = { Q931_CAUSE, Q931_CALL_STATE, -1 };
- 
- static int q931_status(struct pri *pri, q931_call *c, int cause)
-@@ -2441,17 +3074,45 @@
- 	return send_message(pri, c, Q931_INFORMATION, information_ies);
+@@ -2492,12 +3028,34 @@
+ 	return send_message(pri, call, Q931_INFORMATION, keypad_facility_ies);
  }
  
 +static int information_display_ies[] = { Q931_DISPLAY, -1 };
@@ -5231,31 +4972,18 @@
 +	return 0;
 +}
 +
-+/* static int information_special_ies[] = { Q931_IE_SPECIAL, -1 };
-+static int q931_information_special(struct pri *pri, q931_call *c)
-+{
-+	return send_message(pri, c, Q931_FACILITY, information_special_ies);
-+}
-+*/
-+
-+
  static int restart_ack_ies[] = { Q931_CHANNEL_IDENT, Q931_RESTART_INDICATOR, -1 };
  
  static int restart_ack(struct pri *pri, q931_call *c)
  {
- 	c->ourcallstate = Q931_CALL_STATE_NULL;
+ 	UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_NULL);
  	c->peercallstate = Q931_CALL_STATE_NULL;
-+        c->chanflags &= ~FLAG_PREFERRED;
-+        c->chanflags |= FLAG_EXCLUSIVE;
++	c->chanflags &= ~FLAG_PREFERRED;
++	c->chanflags |= FLAG_EXCLUSIVE;
  	return send_message(pri, c, Q931_RESTART_ACKNOWLEDGE, restart_ack_ies);
  }
  
--static int facility_ies[] = { Q931_IE_FACILITY, -1 };
--
- int q931_facility(struct pri*pri, q931_call *c)
- {
- 	return send_message(pri, c, Q931_FACILITY, facility_ies);
-@@ -2465,7 +3126,6 @@
+@@ -2516,7 +3074,6 @@
  		if ((info > 0x2) || (info < 0x00))
  			return 0;
  	}
@@ -5263,7 +4991,7 @@
  	if (info >= 0)
  		c->notify = info & 0x7F;
  	else
-@@ -2508,6 +3168,8 @@
+@@ -2559,6 +3116,8 @@
  
  int q931_call_proceeding(struct pri *pri, q931_call *c, int channel, int info)
  {
@@ -5272,7 +5000,7 @@
  	if (channel) { 
  		c->ds1no = (channel & 0xff00) >> 8;
  		c->ds1explicit = (channel & 0x10000) >> 16;
-@@ -2534,8 +3196,12 @@
+@@ -2585,8 +3144,12 @@
  static int alerting_ies[] = { -1 };
  #endif
  
@@ -5285,9 +5013,9 @@
  	if (!c->proc) 
  		q931_call_proceeding(pri, c, channel, 0);
  	if (info) {
-@@ -2546,14 +3212,130 @@
+@@ -2597,14 +3160,130 @@
  		c->progressmask = 0;
- 	c->ourcallstate = Q931_CALL_STATE_CALL_RECEIVED;
+ 	UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_CALL_RECEIVED);
  	c->peercallstate = Q931_CALL_STATE_CALL_DELIVERED;
 +	c->alert = 1;
  	c->alive = 1;
@@ -5418,8 +5146,8 @@
  	if (channel) { 
  		c->ds1no = (channel & 0xff00) >> 8;
  		c->ds1explicit = (channel & 0x10000) >> 16;
-@@ -2571,9 +3353,39 @@
- 	c->ourcallstate = Q931_CALL_STATE_OVERLAP_RECEIVING;
+@@ -2622,9 +3301,39 @@
+ 	UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_OVERLAP_RECEIVING);
  	c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING;
  	c->alive = 1;
 +	if (network) {
@@ -5458,7 +5186,7 @@
  static void pri_connect_timeout(void *data)
  {
  	struct q931_call *c = data;
-@@ -2628,6 +3440,7 @@
+@@ -2679,6 +3388,7 @@
  
  int q931_connect(struct pri *pri, q931_call *c, int channel, int nonisdn)
  {
@@ -5466,34 +5194,29 @@
  	if (channel) { 
  		c->ds1no = (channel & 0xff00) >> 8;
  		c->ds1explicit = (channel & 0x10000) >> 16;
-@@ -2642,25 +3455,37 @@
+@@ -2693,25 +3403,34 @@
  		c->progressmask = PRI_PROG_CALLED_NOT_ISDN;
  	} else
  		c->progressmask = 0;
--	if (pri->localtype == PRI_CPE)
--		c->ourcallstate = Q931_CALL_STATE_CONNECT_REQUEST;
+-	if(pri->localtype == PRI_NETWORK || pri->switchtype == PRI_SWITCH_QSIG)
++	if(network || pri->switchtype == PRI_SWITCH_QSIG) {
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_ACTIVE);
 -	else
-+	if (network) {
-+		/* WE decide when the call is up and active */
- 		c->ourcallstate = Q931_CALL_STATE_ACTIVE;
 +	} else {
-+	    c->ourcallstate = Q931_CALL_STATE_CONNECT_REQUEST;
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_CONNECT_REQUEST);
 +	}
  	c->peercallstate = Q931_CALL_STATE_ACTIVE;
  	c->alive = 1;
 +	c->con_acked = 0;
- 	/* Setup timer */
+ 	/* Connect request timer */
  	if (c->retranstimer)
  		pri_schedule_del(pri, c->retranstimer);
  	c->retranstimer = 0;
--	if ((pri->localtype == PRI_CPE) && (!pri->subchannel))
-+	if (!network && (!pri->subchannel)) {
-+		/* make sure that CPEs get a CONNECT_ACKNOWLEDGE */
+ 	if ((c->ourcallstate == Q931_CALL_STATE_CONNECT_REQUEST) && (!pri->subchannel))
  		c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T313], pri_connect_timeout, c);
 -	return send_message(pri, c, Q931_CONNECT, connect_ies);
-+	}
-+	if ((pri->localtype != PRI_CPE) && (pri->localtype != BRI_CPE) && (pri->localtype != BRI_CPE_PTMP)) {
-+	    // networks may send datetime
++	if (network) {
++	    /* networks may send datetime */
 +	    return send_message(pri, c, Q931_CONNECT, connect_NET_ies);
 +	} else {
 +	    return send_message(pri, c, Q931_CONNECT, connect_ies);
@@ -5506,10 +5229,10 @@
  int q931_release(struct pri *pri, q931_call *c, int cause)
  {
 +	int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
- 	c->ourcallstate = Q931_CALL_STATE_RELEASE_REQUEST;
+ 	UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_RELEASE_REQUEST);
  	/* c->peercallstate stays the same */
  	if (c->alive) {
-@@ -2676,7 +3501,14 @@
+@@ -2727,7 +3446,14 @@
  			} else {
  				c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T308], pri_release_finaltimeout, c);
  			}
@@ -5525,7 +5248,7 @@
  		} else
  			return send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies); /* Yes, release_ies, not release_complete_ies */
  	} else
-@@ -2688,7 +3520,7 @@
+@@ -2739,7 +3465,7 @@
  int q931_restart(struct pri *pri, int channel)
  {
  	struct q931_call *c;
@@ -5534,7 +5257,7 @@
  	if (!c)
  		return -1;
  	if (!channel)
-@@ -2705,10 +3537,12 @@
+@@ -2756,10 +3482,12 @@
  	return send_message(pri, c, Q931_RESTART, restart_ies);
  }
  
@@ -5544,10 +5267,10 @@
  int q931_disconnect(struct pri *pri, q931_call *c, int cause)
  {
 +	int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
- 	c->ourcallstate = Q931_CALL_STATE_DISCONNECT_REQUEST;
+ 	UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_DISCONNECT_REQUEST);
  	c->peercallstate = Q931_CALL_STATE_DISCONNECT_INDICATION;
  	if (c->alive) {
-@@ -2720,14 +3554,27 @@
+@@ -2771,14 +3499,30 @@
  		if (c->retranstimer)
  			pri_schedule_del(pri, c->retranstimer);
  		c->retranstimer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T305], pri_disconnect_timeout, c);
@@ -5570,17 +5293,21 @@
  static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY, Q931_IE_USER_USER,
  	Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, -1 };
  
++static int setup_cpe_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_IE_USER_USER,
++	Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, -1 };
++
 +static int setup_bri_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY, Q931_IE_USER_USER,
 +	Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, Q931_HIGH_LAYER_COMPAT, Q931_LOW_LAYER_COMPAT, -1 };
 +
  static int gr303_setup_ies[] =  { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, -1 };
  
  static int cis_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_CALLED_PARTY_NUMBER, -1 };
-@@ -2735,7 +3582,12 @@
+@@ -2786,7 +3530,13 @@
  int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
  {
  	int res;
 -	
++	int network = pri->localtype == PRI_NETWORK || pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP;
 +
 + 	if (pri->localtype == BRI_NETWORK_PTMP) {
 + 	    c->tei = 127;
@@ -5590,7 +5317,7 @@
  	
  	c->transcapability = req->transmode;
  	c->transmoderate = TRANS_MODE_64_CIRCUIT;
-@@ -2760,6 +3612,7 @@
+@@ -2811,6 +3561,7 @@
  		c->chanflags = FLAG_EXCLUSIVE;
  	else if (c->channelno)
  		c->chanflags = FLAG_PREFERRED;
@@ -5598,27 +5325,36 @@
  	if (req->caller) {
  		libpri_copy_string(c->callernum, req->caller, sizeof(c->callernum));
  		c->callerplan = req->callerplan;
-@@ -2819,14 +3672,19 @@
+@@ -2866,18 +3617,25 @@
+ 
+ 	pri_call_add_standard_apdus(pri, c);
+ 
+-	if (pri->subchannel)
++	if (pri->subchannel) {
  		res = send_message(pri, c, Q931_SETUP, gr303_setup_ies);
- 	else if (c->justsignalling)
+-	else if (c->justsignalling)
++	} else if (c->justsignalling) {
  		res = send_message(pri, c, Q931_SETUP, cis_setup_ies);
-+	else if (pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP) 
+-	else
++	} else if (pri->localtype == BRI_NETWORK || pri->localtype == BRI_NETWORK_PTMP) {
 +		res = send_message(pri, c, Q931_SETUP, setup_bri_ies);
- 	else
++	} else if (network) {
  		res = send_message(pri, c, Q931_SETUP, setup_ies);
-+
++	} else {
++		res = send_message(pri, c, Q931_SETUP, setup_cpe_ies);
++	}	
  	if (!res) {
  		c->alive = 1;
  		/* make sure we call PRI_EVENT_HANGUP_ACK once we send/receive RELEASE_COMPLETE */
  		c->sendhangupack = 1;
- 		c->ourcallstate = Q931_CALL_STATE_CALL_INITIATED;
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_CALL_INITIATED);
  		c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING;	
 +		c->t303timer = pri_schedule_event(pri, pri->timers[PRI_TIMER_T303], pri_setup_response_timeout, c);
 +		c->t303running = 1;
  	}
  	return res;
  	
-@@ -2842,7 +3700,11 @@
+@@ -2893,7 +3651,11 @@
  	if (cause > -1) {
  		c->cause = cause;
  		c->causecode = CODE_CCITT;
@@ -5631,7 +5367,7 @@
  		/* release_ies has CAUSE in it */
  		res = send_message(pri, c, Q931_RELEASE_COMPLETE, release_ies);
  	} else
-@@ -2867,6 +3729,125 @@
+@@ -2918,6 +3680,125 @@
  	return 0;
  }
  
@@ -5757,7 +5493,7 @@
  int q931_hangup(struct pri *pri, q931_call *c, int cause)
  {
  	int disconnect = 1;
-@@ -2878,7 +3859,7 @@
+@@ -2929,7 +3810,7 @@
  	/* If mandatory IE was missing, insist upon that cause code */
  	if (c->cause == PRI_CAUSE_MANDATORY_IE_MISSING)
  		cause = c->cause;
@@ -5766,7 +5502,7 @@
  		/* We'll send RELEASE_COMPLETE with these causes */
  		disconnect = 0;
  		release_compl = 1;
-@@ -2892,7 +3873,7 @@
+@@ -2943,7 +3824,7 @@
  	case Q931_CALL_STATE_NULL:
  		if (c->peercallstate == Q931_CALL_STATE_NULL)
  			/* free the resources if we receive or send REL_COMPL */
@@ -5775,7 +5511,7 @@
  		else if (c->peercallstate == Q931_CALL_STATE_RELEASE_REQUEST)
  			q931_release_complete(pri,c,cause);
  		break;
-@@ -2918,6 +3899,11 @@
+@@ -2967,6 +3848,11 @@
  		/* received SETUP_ACKNOWLEDGE */
  		/* send DISCONNECT in general */
  		if (c->peercallstate != Q931_CALL_STATE_NULL && c->peercallstate != Q931_CALL_STATE_DISCONNECT_REQUEST && c->peercallstate != Q931_CALL_STATE_DISCONNECT_INDICATION && c->peercallstate != Q931_CALL_STATE_RELEASE_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART) {
@@ -5787,7 +5523,7 @@
  			if (disconnect)
  				q931_disconnect(pri,c,cause);
  			else if (release_compl)
-@@ -2933,8 +3919,14 @@
+@@ -2986,8 +3872,14 @@
  		break;
  	case Q931_CALL_STATE_DISCONNECT_INDICATION:
  		/* received DISCONNECT */
@@ -5802,7 +5538,7 @@
  			q931_release(pri,c,cause);
  		}
  		break;
-@@ -2948,19 +3940,17 @@
+@@ -3001,19 +3893,17 @@
  		pri_error(pri, "q931_hangup shouldn't be called in this state, ourstate %s, peerstate %s\n",callstate2str(c->ourcallstate),callstate2str(c->peercallstate));
  		break;
  	default:
@@ -5825,7 +5561,7 @@
  	q931_call *c;
  	q931_ie *ie;
  	unsigned int x;
-@@ -2972,6 +3962,7 @@
+@@ -3025,6 +3915,7 @@
  	int codeset, cur_codeset;
  	int last_ie[8];
  	struct apdu_event *cur = NULL;
@@ -5833,7 +5569,7 @@
  
  	memset(last_ie, 0, sizeof(last_ie));
  	if (pri->debug & PRI_DEBUG_Q931_DUMP)
-@@ -2985,13 +3976,13 @@
+@@ -3038,13 +3929,13 @@
  		   KLUDGE this by changing byte 4 from a 0xf (SERVICE) 
  		   to a 0x7 (SERVICE ACKNOWLEDGE) */
  		h->raw[h->crlen + 2] -= 0x8;
@@ -5849,7 +5585,7 @@
  	if (!c) {
  		pri_error(pri, "Unable to locate call %d\n", q931_cr(h));
  		return -1;
-@@ -3014,6 +4005,7 @@
+@@ -3067,6 +3958,7 @@
  	case Q931_SETUP:
  		if (pri->debug & PRI_DEBUG_Q931_STATE)
  			pri_message(pri, "-- Processing Q.931 Call Setup\n");
@@ -5857,92 +5593,53 @@
  		c->channelno = -1;
  		c->slotmap = -1;
  		c->chanflags = 0;
-@@ -3034,28 +4026,44 @@
- 		c->callername[0] = '\0';
- 		c->callerani[0] = '\0';
- 		c->callerplanani = -1;
--		c->redirectingplan = -1;
--		c->redirectingpres = -1;
--		c->redirectingreason = -1;
--		c->origcalledplan = -1;
--		c->origcalledpres = -1;
--		c->origredirectingreason = -1;
-+                c->redirectingplan = -1;
-+                c->redirectingpres = -1;
-+                c->redirectingreason = -1;
-+                c->origcalledplan = -1;
-+                c->origcalledpres = -1;
-+                c->origredirectingreason = -1;
- 		c->redirectingnum[0] = '\0';
- 		c->origcallednum[0] = '\0';
- 		c->redirectingname[0] = '\0';
- 		c->origcalledname[0] = '\0';
--		c->useruserprotocoldisc = -1; 
-+                c->useruserprotocoldisc = -1; 
- 		c->useruserinfo[0] = '\0';
+@@ -3102,17 +3994,30 @@
  		c->complete = 0;
  		c->nonisdn = 0;
  		c->aoc_units = -1;
--		/* Fall through */
 + 		c->digits[0] = '\0';
 + 		c->display[0] = '\0';
 +		c->progress = -1;
 +		c->progressmask = 0;
-+		break;
- 	case Q931_CONNECT:
-+ 		if (c->t303timer) {
-+ 		    c->t303running = 0;
-+ 		    pri_schedule_del(pri, c->t303timer);
-+     		}
-+ 		c->useruserinfo[0] = '\0';
-+		c->t303timer = 0;
-+ 		c->progress = -1;
-+ 		break;
+ 		/* Fall through */
+-	case Q931_CONNECT:
  	case Q931_ALERTING:
  	case Q931_PROGRESS:
--		c->useruserinfo[0] = '\0';
--		c->cause = -1;
-+ 		c->useruserinfo[0] = '\0';
- 	case Q931_CALL_PROCEEDING:
-+ 		if (c->t303timer) {
-+ 		    c->t303running = 0;
-+ 		    pri_schedule_del(pri, c->t303timer);
-+ 		}
-+ 		c->t303timer = 0;
+ 		c->useruserinfo[0] = '\0';
+ 		c->cause = -1;
+-		/* Fall through */
+-	case Q931_CALL_PROCEEDING:
  		c->progress = -1;
  		c->progressmask = 0;
  		break;
-@@ -3066,20 +4074,22 @@
- 		break;
- 	case Q931_RELEASE:
- 	case Q931_DISCONNECT:
--		c->cause = -1;
--		c->causecode = -1;
--		c->causeloc = -1;
--		c->aoc_units = -1;
-+//		c->aoc_units = -1;
++	case Q931_CALL_PROCEEDING:
++		/* Fall through */
++	case Q931_CONNECT:
++ 		if (c->t303timer) {
++ 		    c->t303running = 0;
++ 		    pri_schedule_del(pri, c->t303timer);
++  		}
 + 		c->useruserinfo[0] = '\0';
++		c->t303timer = 0;
++		c->progress = -1;
++		c->progressmask = 0;
++ 		break;
+ 	case Q931_CONNECT_ACKNOWLEDGE:
  		if (c->retranstimer)
  			pri_schedule_del(pri, c->retranstimer);
+@@ -3128,6 +4033,11 @@
+ 			pri_schedule_del(pri, c->retranstimer);
  		c->retranstimer = 0;
--		c->useruserinfo[0] = '\0';
+ 		c->useruserinfo[0] = '\0';
 +		if (c->t303timer) {
 +		    c->t303running = 0;
 +		    pri_schedule_del(pri, c->t303timer);
-+    		}
++ 		}
 +		c->t303timer = 0;
  		break;
  	case Q931_RELEASE_COMPLETE:
  		if (c->retranstimer)
--			pri_schedule_del(pri, c->retranstimer);
-+		    pri_schedule_del(pri, c->retranstimer);
- 		c->retranstimer = 0;
--		c->useruserinfo[0] = '\0';
-+ 		c->useruserinfo[0] = '\0';
- 	case Q931_STATUS:
- 		c->cause = -1;
- 		c->causecode = -1;
-@@ -3096,22 +4106,32 @@
+@@ -3151,22 +4061,32 @@
  	case Q931_STATUS_ENQUIRY:
  		break;
  	case Q931_SETUP_ACKNOWLEDGE:
@@ -5979,16 +5676,16 @@
  	case Q931_SUSPEND_ACKNOWLEDGE:
  	case Q931_SUSPEND_REJECT:
  		pri_error(pri, "!! Not yet handling pre-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
-@@ -3120,7 +4140,7 @@
- 		pri_error(pri, "!! Don't know how to post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
+@@ -3175,7 +4095,7 @@
+ 		pri_error(pri, "!! Don't know how to pre-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
  		q931_status(pri,c, PRI_CAUSE_MESSAGE_TYPE_NONEXIST);
  		if (c->newcall) 
 -			q931_destroycall(pri,c->cr);
 +			q931_destroycall(pri,c->cr,c->tei);
  		return -1;
  	}
- 	memset(mandies, 0, sizeof(mandies));
-@@ -3200,12 +4220,19 @@
+ 	/* Handle IEs */
+@@ -3256,12 +4176,19 @@
  	missingmand = 0;
  	for (x=0;x<MAX_MAND_IES;x++) {
  		if (mandies[x]) {
@@ -6013,7 +5710,7 @@
  		}
  	}
  	
-@@ -3214,7 +4241,7 @@
+@@ -3270,7 +4197,7 @@
  	case Q931_RESTART:
  		if (missingmand) {
  			q931_status(pri, c, PRI_CAUSE_MANDATORY_IE_MISSING);
@@ -6021,8 +5718,8 @@
 +			q931_destroycall(pri, c->cr, c->tei);
  			break;
  		}
- 		c->ourcallstate = Q931_CALL_STATE_RESTART;
-@@ -3232,6 +4259,7 @@
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_RESTART);
+@@ -3288,6 +4215,7 @@
  		}
  		/* Must be new call */
  		if (!c->newcall) {
@@ -6030,7 +5727,7 @@
  			break;
  		}
  		if (c->progressmask & PRI_PROG_CALLER_NOT_ISDN)
-@@ -3249,16 +4277,20 @@
+@@ -3305,16 +4233,20 @@
  		pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
  		pri->ev.ring.callingpres = c->callerpres;
  		pri->ev.ring.callingplan = c->callerplan;
@@ -6045,15 +5742,15 @@
  		pri->ev.ring.calledplan = c->calledplan;
  		libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr));
 -		libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum));
-+		if (!strlen(c->callednum) && strlen(c->digitbuf)) {
-+		    libpri_copy_string(pri->ev.ring.callednum, c->digitbuf, sizeof(pri->ev.ring.callednum));
++		if (!strlen(c->callednum) && strlen(c->keypad_digits)) {
++		    libpri_copy_string(pri->ev.ring.callednum, c->keypad_digits, sizeof(pri->ev.ring.callednum));
 +		} else {
 +		    libpri_copy_string(pri->ev.ring.callednum, c->callednum, sizeof(pri->ev.ring.callednum));
 +		}
  		libpri_copy_string(pri->ev.ring.origcalledname, c->origcalledname, sizeof(pri->ev.ring.origcalledname));
  		libpri_copy_string(pri->ev.ring.origcallednum, c->origcallednum, sizeof(pri->ev.ring.origcallednum));
  		libpri_copy_string(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum));
-@@ -3268,11 +4300,13 @@
+@@ -3324,11 +4256,13 @@
  		pri->ev.ring.redirectingreason = c->redirectingreason;
  		pri->ev.ring.origredirectingreason = c->origredirectingreason;
  		pri->ev.ring.flexible = ! (c->chanflags & FLAG_EXCLUSIVE);
@@ -6068,23 +5765,23 @@
  		pri->ev.ring.redirectingreason = c->redirectingreason;
  		pri->ev.ring.progress = c->progress;
  		pri->ev.ring.progressmask = c->progressmask;
-@@ -3282,6 +4316,9 @@
- 			q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
- 			break;
+@@ -3340,6 +4274,9 @@
  		}
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_CALL_DELIVERED);
+ 		c->peercallstate = Q931_CALL_STATE_CALL_RECEIVED;
 +		if (pri->localtype == BRI_NETWORK_PTMP) {
 +		    l2c = q921_getcall(pri, c, tei);
 +		}
- 		c->ourcallstate = Q931_CALL_STATE_CALL_DELIVERED;
- 		c->peercallstate = Q931_CALL_STATE_CALL_RECEIVED;
  		pri->ev.e = PRI_EVENT_RINGING;
-@@ -3302,17 +4339,24 @@
+ 		pri->ev.ringing.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
+ 		pri->ev.ringing.cref = c->cr;
+@@ -3368,17 +4305,24 @@
  			q931_status(pri, c, PRI_CAUSE_WRONG_MESSAGE);
  			break;
  		}
 +  		/* TEI got the call */
 +  		c->tei = tei;
- 		c->ourcallstate = Q931_CALL_STATE_ACTIVE;
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_ACTIVE);
  		c->peercallstate = Q931_CALL_STATE_CONNECT_REQUEST;
  		pri->ev.e = PRI_EVENT_ANSWER;
  		pri->ev.answer.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
@@ -6103,7 +5800,7 @@
  		if (c->justsignalling) {  /* Make sure WE release when we initiatie a signalling only connection */
  			q931_release(pri, c, PRI_CAUSE_NORMAL_CLEARING);
  			break;
-@@ -3320,23 +4364,43 @@
+@@ -3386,23 +4330,43 @@
  			return Q931_RES_HAVEEVENT;
  	case Q931_FACILITY:
  		if (c->newcall) {
@@ -6160,7 +5857,7 @@
  			break;
  		}
  		pri->ev.e = PRI_EVENT_PROGRESS;
-@@ -3354,6 +4418,11 @@
+@@ -3420,6 +4384,11 @@
  			q931_status(pri,c,PRI_CAUSE_WRONG_MESSAGE);
  			break;
  		}
@@ -6172,19 +5869,16 @@
  		pri->ev.proceeding.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
  		if (mh->msg == Q931_CALL_PROCEEDING) {
  			pri->ev.e = PRI_EVENT_PROCEEDING;
-@@ -3381,16 +4450,21 @@
- 			break;
+@@ -3447,17 +4416,18 @@
  		}
- 		if (c->ourcallstate != Q931_CALL_STATE_CONNECT_REQUEST) {
-+		    if ((c->ourcallstate == Q931_CALL_STATE_ACTIVE) && (c->con_acked == 0) && (network)) {
-+			/* sending a CONNECT_ACKNOWLEDGE is optional for CPEs */
-+		    } else {
+ 		if (!(c->ourcallstate == Q931_CALL_STATE_CONNECT_REQUEST) &&
+ 		    !(c->ourcallstate == Q931_CALL_STATE_ACTIVE &&
+-		      (pri->localtype == PRI_NETWORK || pri->switchtype == PRI_SWITCH_QSIG))) {
++		      (network || pri->switchtype == PRI_SWITCH_QSIG))) {
  			q931_status(pri,c,PRI_CAUSE_WRONG_MESSAGE);
--			break;
-+		    }
-+		    break;
+ 			break;
  		}
- 		c->ourcallstate = Q931_CALL_STATE_ACTIVE;
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_ACTIVE);
  		c->peercallstate = Q931_CALL_STATE_ACTIVE;
 +		c->con_acked = 1;
  		break;
@@ -6196,35 +5890,11 @@
  			break;
  		}
  		if (c->newcall) {
-@@ -3429,32 +4503,69 @@
- 			if (res)
- 				return res;
+@@ -3498,30 +4468,46 @@
  		}
--		break;
-+		if (c->ourcallstate != c->sugcallstate) {
-+            	    pri_error(pri, "updating callstate, peercallstate %d to %d\n", c->peercallstate, c->sugcallstate);
-+        	    c->ourcallstate = c->sugcallstate;
-+            	    if ((c->sugcallstate != Q931_CALL_STATE_ACTIVE) &&(c->sugcallstate != Q931_CALL_STATE_CALL_INITIATED)) {
-+                        /* pass hangup to upper layer! */
-+                        if (c->alive) {
-+                                pri->ev.e = PRI_EVENT_HANGUP;
-+                                res = Q931_RES_HAVEEVENT;
-+                                c->alive = 0;
-+                        } else if (c->sendhangupack) {
-+                                res = Q931_RES_HAVEEVENT;
-+                                pri->ev.e = PRI_EVENT_HANGUP_ACK;
-+                                q931_hangup(pri, c, c->cause);
-+                        } else {
-+                                q931_hangup(pri, c, c->cause);
-+                                res = 0;
-+			if (res)
-+				return res;
-+                        }
-+		    }
-+                }
-+                break;
+ 		break;
  	case Q931_RELEASE_COMPLETE:
--		c->ourcallstate = Q931_CALL_STATE_NULL;
+-		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_NULL);
 -		c->peercallstate = Q931_CALL_STATE_NULL;
 -		pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
 -		pri->ev.hangup.cause = c->cause;
@@ -6235,64 +5905,56 @@
 -		c->useruserinfo[0] = '\0';
 -		/* Free resources */
 -		if (c->alive) {
--			pri->ev.e = PRI_EVENT_HANGUP;
--			res = Q931_RES_HAVEEVENT;
--			c->alive = 0;
--		} else if (c->sendhangupack) {
--			res = Q931_RES_HAVEEVENT;
--			pri->ev.e = PRI_EVENT_HANGUP_ACK;
--			pri_hangup(pri, c, c->cause);
--		} else
--			res = 0;
--		if (res)
--			return res;
--		else
--			q931_hangup(pri,c,c->cause);
-+    		if (pri->localtype != BRI_NETWORK_PTMP) {
++ 		if (pri->localtype != BRI_NETWORK_PTMP) {
 +		    /* only stop the T303 timer if WE are not a BRI PTMP network */
 +		    if (c->t303timer) {
 + 			c->t303running = 0;
 + 			pri_schedule_del(pri, c->t303timer);
 + 		        c->t303timer = 0;
 +		    }
-+     		}
-+
++  		}
 + 		if ((pri->localtype != BRI_NETWORK_PTMP) || (c->tei == tei)) {
-+ 		    c->ourcallstate = Q931_CALL_STATE_NULL;
-+ 		    c->peercallstate = Q931_CALL_STATE_NULL;
-+ 		    pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
-+ 		    pri->ev.hangup.cref = c->cr;          		
-+ 		    pri->ev.hangup.cause = c->cause;      		
-+ 		    pri->ev.hangup.call = c;              		
-+        	    libpri_copy_string(pri->ev.hangup.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo));
++		    UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_NULL);
++		    c->peercallstate = Q931_CALL_STATE_NULL;
++		    pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
++		    pri->ev.hangup.cause = c->cause;
++		    pri->ev.hangup.cref = c->cr;
++		    pri->ev.hangup.call = c;
++		    pri->ev.hangup.aoc_units = c->aoc_units;
++		    libpri_copy_string(pri->ev.hangup.useruserinfo, c->useruserinfo, sizeof(pri->ev.hangup.useruserinfo));
 +		    c->useruserinfo[0] = '\0';
-+ 		    /* Free resources */
-+ 		    if (c->alive) {
-+  			pri->ev.e = PRI_EVENT_HANGUP;
-+  			res = Q931_RES_HAVEEVENT;
-+  			c->alive = 0;
-+ 		    } else if (c->sendhangupack) {
-+  			res = Q931_RES_HAVEEVENT;
-+  			pri->ev.e = PRI_EVENT_HANGUP_ACK;
-+  			pri_hangup(pri, c, c->cause, -1);
-+ 		    } else
-+  			res = 0;
-+ 		    if (res)
-+  			return res;
-+ 		    else
-+  			q931_hangup(pri,c,c->cause);
-+ 		} else {
-+ 		    // BRI_NET_PTMP
-+ 		    // ignoring relase_complete
++		    /* Free resources */
++		    if (c->alive) {
+ 			pri->ev.e = PRI_EVENT_HANGUP;
+ 			res = Q931_RES_HAVEEVENT;
+ 			c->alive = 0;
+-		} else if (c->sendhangupack) {
++		    } else if (c->sendhangupack) {
+ 			res = Q931_RES_HAVEEVENT;
+ 			pri->ev.e = PRI_EVENT_HANGUP_ACK;
+-			pri_hangup(pri, c, c->cause);
+-		} else
++			pri_hangup(pri, c, c->cause, -1);
++		    } else
+ 			res = 0;
+-		if (res)
++		    if (res)
+ 			return res;
+-		else
++		    else
+ 			q931_hangup(pri,c,c->cause);
++		} else {
++ 		    /* BRI_NET_PTMP
++ 		       ignoring relase_complete */
 + 		    res = q921_handle_hangup(pri,c,tei);
 + 		    if (res)
 + 			return res;
-+ 		}
++		}
  		break;
  	case Q931_RELEASE:
  		if (missingmand) {
-@@ -3469,11 +4580,12 @@
- 		c->ourcallstate = Q931_CALL_STATE_NULL;
+@@ -3536,11 +4522,12 @@
+ 		UPDATE_OURCALLSTATE(pri, c, Q931_CALL_STATE_NULL);
  		pri->ev.e = PRI_EVENT_HANGUP;
  		pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
 -		pri->ev.hangup.cause = c->cause;
@@ -6306,7 +5968,7 @@
  		c->useruserinfo[0] = '\0';
  		/* Don't send release complete if they send us release 
  		   while we sent it, assume a NULL state */
-@@ -3497,12 +4609,17 @@
+@@ -3564,12 +4551,17 @@
  		/* Return such an event */
  		pri->ev.e = PRI_EVENT_HANGUP_REQ;
  		pri->ev.hangup.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
@@ -6327,7 +5989,7 @@
  		if (c->alive)
  			return Q931_RES_HAVEEVENT;
  		else
-@@ -3533,7 +4650,7 @@
+@@ -3602,7 +4594,7 @@
  		pri->ev.e = PRI_EVENT_INFO_RECEIVED;
  		pri->ev.ring.call = c;
  		pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
@@ -6336,7 +5998,7 @@
  		libpri_copy_string(pri->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(pri->ev.ring.callingsubaddr));
  		pri->ev.ring.complete = c->complete; 	/* this covers IE 33 (Sending Complete) */
  		return Q931_RES_HAVEEVENT;
-@@ -3553,7 +4670,6 @@
+@@ -3622,7 +4614,6 @@
  		pri->ev.e = PRI_EVENT_SETUP_ACK;
  		pri->ev.setup_ack.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
  		pri->ev.setup_ack.call = c;
@@ -6344,7 +6006,7 @@
  		cur = c->apdus;
  		while (cur) {
  			if (!cur->sent && cur->message == Q931_FACILITY) {
-@@ -3569,19 +4685,53 @@
+@@ -3638,19 +4629,53 @@
  		pri->ev.notify.channel = c->channelno;
  		pri->ev.notify.info = c->notify;
  		return Q931_RES_HAVEEVENT;
@@ -6402,7 +6064,7 @@
  	case Q931_SUSPEND_ACKNOWLEDGE:
  	case Q931_SUSPEND_REJECT:
  		pri_error(pri, "!! Not yet handling post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
-@@ -3591,7 +4741,7 @@
+@@ -3660,7 +4685,7 @@
  		pri_error(pri, "!! Don't know how to post-handle message type %s (%d)\n", msg2str(mh->msg), mh->msg);
  		q931_status(pri,c, PRI_CAUSE_MESSAGE_TYPE_NONEXIST);
  		if (c->newcall) 
@@ -6411,9 +6073,9 @@
  		return -1;
  	}
  	return 0;
-diff -urN libpri-1.2.4.orig/README libpri-1.2.4/README
---- libpri-1.2.4.orig/README	2006-02-15 18:59:38.000000000 +0100
-+++ libpri-1.2.4/README	2006-01-18 12:28:07.000000000 +0100
+diff -urN libpri-1.4.1.orig/README libpri-1.4.1/README
+--- libpri-1.4.1.orig/README	2006-02-15 19:01:03.000000000 +0100
++++ libpri-1.4.1/README	2007-07-11 14:25:15.000000000 +0200
 @@ -1,6 +1,7 @@
 -libpri: An implementation of Primary Rate ISDN
 -
@@ -6445,19 +6107,3 @@
  
  
  How do I report bugs or contribute?
-diff -urN libpri-1.2.4.orig/TODO libpri-1.2.4/TODO
---- libpri-1.2.4.orig/TODO	2005-11-29 19:39:18.000000000 +0100
-+++ libpri-1.2.4/TODO	2006-01-18 12:28:07.000000000 +0100
-@@ -2,9 +2,7 @@
- -- D-Channel Backup
- -- Test against 4e
- 
--Q.921:
---- Support unnumbered information frames
--
- Q.931:
---- Locking Shift IE
---- Implement the 11 missing Q.931 timers
-+-- Locking Shift IE (you did that already, didnt you??)
-+-- Implement the 10 missing Q.931 timers
-+-- more facilities

Modified: libpri/trunk/debian/patches/libname.dpatch
===================================================================
--- libpri/trunk/debian/patches/libname.dpatch	2007-07-27 19:04:49 UTC (rev 3858)
+++ libpri/trunk/debian/patches/libname.dpatch	2007-07-28 08:17:25 UTC (rev 3859)
@@ -11,7 +11,7 @@
 diff -urNad libpri-1.2.3~/Makefile libpri-1.2.3/Makefile
 --- libpri-1.2.3~/Makefile	2006-04-30 15:17:47.000000000 +0000
 +++ libpri-1.2.3/Makefile	2006-06-10 13:48:23.000000000 +0000
-@@ -32,16 +32,22 @@
+@@ -32,14 +32,20 @@
  OSARCH=$(shell uname -s)
  PROC?=$(shell uname -m)
  
@@ -20,8 +20,6 @@
 +else
 +LIBNAME=pri
 +endif
- TOBJS=testpri.o
- T2OBJS=testprilib.o
 -STATIC_LIBRARY=libpri.a
 -DYNAMIC_LIBRARY=libpri.so.1.0
 +STATIC_LIBRARY=lib$(LIBNAME).a
@@ -35,7 +33,7 @@
 +INCLUDE_DIR=$(INSTALL_PREFIX)$(INSTALL_BASE)/include/$(LIB_SUF)
 +SOFLAGS = -Wl,-hlib$(LIBNAME).so.1.0
  LDCONFIG = /sbin/ldconfig
- ifneq (,$(findstring $(OSARCH), Linux GNU/kFreeBSD))
+ ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX))
  LDCONFIG_FLAGS=-n
 @@ -55,7 +61,7 @@
  CFLAGS += -DSOLARIS -I../zaptel-solaris
@@ -56,7 +54,7 @@
  ifneq (${OSARCH},SunOS)
 -	install -m 644 libpri.h $(INSTALL_PREFIX)$(INSTALL_BASE)/include
  	install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
- 	if [ -x /usr/sbin/sestatus ] && ( /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"); then  restorecon -v $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/$(DYNAMIC_LIBRARY); fi
+ 	if [ -x /usr/sbin/sestatus ] && ( /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"); then /sbin/restorecon -v $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/$(DYNAMIC_LIBRARY); fi
 -	( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.1.0 libpri.so ; ln -sf libpri.so.1.0 libpri.so.1 )
 +	( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf lib$(LIBNAME).so.1.0 lib$(LIBNAME).so ; ln -sf lib$(LIBNAME).so.1.0 lib$(LIBNAME).so.1 )
  	install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib

Modified: libpri/trunk/debian/rules
===================================================================
--- libpri/trunk/debian/rules	2007-07-27 19:04:49 UTC (rev 3858)
+++ libpri/trunk/debian/rules	2007-07-28 08:17:25 UTC (rev 3859)
@@ -10,7 +10,7 @@
 
 CFLAGS = -Wall -g
 
-USE_BRISTUFF=0
+USE_BRISTUFF=1
 
 ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
 	CFLAGS += -O0




More information about the Pkg-voip-commits mailing list