diff -ur libpri-1.0.3/libpri.h libpri-1.0.3-vihai/libpri.h
--- libpri-1.0.3/libpri.h	2004-12-29 19:24:45.556592624 +0100
+++ libpri-1.0.3-vihai/libpri.h	2004-12-29 19:23:48.039507317 +0100
@@ -82,6 +82,8 @@
 #define PRI_EVENT_RESUME_REQ    21	/* unpark */
 #define PRI_EVENT_DISPLAY_RECEIVED    22
 #define PRI_EVENT_FACILITY	23	/* Facility */
+#define PRI_EVENT_DCHAN_REALLY_UP     24
+#define PRI_EVENT_DCHAN_REALLY_DOWN   25
 
 /* Simple states */
 #define PRI_STATE_DOWN		0
Only in libpri-1.0.3-vihai: libpri.h.orig
diff -ur libpri-1.0.3/pri.c libpri-1.0.3-vihai/pri.c
--- libpri-1.0.3/pri.c	2004-12-29 19:24:45.558592279 +0100
+++ libpri-1.0.3-vihai/pri.c	2004-12-29 19:23:16.930867841 +0100
@@ -86,6 +86,7 @@
 		p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
 		p->master = master;
 		p->callpool = &p->localpool;
+		p->spoofing_state = 0;
 #ifdef LIBPRI_COUNTERS
 		p->q921_rxcount = 0;
 		p->q921_txcount = 0;
diff -ur libpri-1.0.3/pri_internal.h libpri-1.0.3-vihai/pri_internal.h
--- libpri-1.0.3/pri_internal.h	2004-12-29 19:24:45.560591934 +0100
+++ libpri-1.0.3-vihai/pri_internal.h	2004-12-29 19:23:16.932867496 +0100
@@ -57,6 +57,7 @@
 	struct pri_sched pri_sched[MAX_SCHED];	/* Scheduled events */
 	int debug;			/* Debug stuff */
 	int state;			/* State of D-channel */
+	int spoofing_state;
 	int switchtype;		/* Switch type */
 	int nsf;		/* Network-Specific Facility (if any) */
 	int localtype;		/* Local network type (unknown, network, cpe) */
Only in libpri-1.0.3-vihai: pri_internal.h.orig
diff -ur libpri-1.0.3/q921.c libpri-1.0.3-vihai/q921.c
--- libpri-1.0.3/q921.c	2004-12-29 19:24:45.570590207 +0100
+++ libpri-1.0.3-vihai/q921.c	2004-12-29 19:23:16.934867152 +0100
@@ -687,11 +687,34 @@
 	q921_transmit(pri, &h, 4);
 }
 
+static void q921_flush_txqueue(struct pri *pri, char tei)
+{
+	int teio=tei - Q921_TEI_BASE;
+	if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
+
+	if(pri->txqueue[teio]) {
+		q921_frame *current_packet=pri->txqueue[teio];
+		while(current_packet) {
+			q921_transmit(pri, (q921_h *)&pri->txqueue[teio]->h,
+					 pri->txqueue[teio]->len);
+			current_packet = current_packet->next;
+		}
+
+		pri->t200_timer[teio] = pri_schedule_event2(pri, T_200, t200_expire, pri, tei);
+	}
+}
+
 static void t200_expire(void *vpri, int tei)
 {
 	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) {
+		pri_error("T200 expired while link not ESTABLISHED\n");
+		return;
+	}
+
 	if (pri->txqueue[teio]) {
 		/* Retransmit first packet in the queue, setting the poll bit */
 		if (pri->debug & PRI_DEBUG_Q921_STATE)
@@ -703,30 +726,33 @@
 		pri->v_na[teio] = pri->v_r[teio];
 		pri->solicitfbit[teio] = 1;
 		pri->retrans[teio]++;
-      /* Up to three retransmissions */
-      if (pri->retrans[teio] < N_200) {
-         /* Reschedule t200_timer */
-         if (pri->debug & PRI_DEBUG_Q921_STATE)
-            pri_message("-- Retransmitting %d bytes\n", pri->txqueue[teio]->len);
-		if (pri->busy[teio]) 
-			q921_rr(pri, 1, 0, tei);
-		else {
-			if (!pri->txqueue[teio]->transmitted) 
-				pri_error("!! Not good - head of queue has not been transmitted yet\n");
+
+		/* Up to three retransmissions */
+		if (pri->retrans[teio] < N_200) {
+			 /* Reschedule t200_timer */
+			if (pri->debug & PRI_DEBUG_Q921_STATE)
+			pri_message("-- Retransmitting %d bytes\n", pri->txqueue[teio]->len);
+
 			q921_transmit(pri, (q921_h *)&pri->txqueue[teio]->h, pri->txqueue[teio]->len);
+			if (pri->debug & PRI_DEBUG_Q921_STATE) 
+				pri_message("-- Rescheduling retransmission (%d)\n", pri->retrans[teio]);
+
+			pri->t200_timer[teio] = pri_schedule_event2(pri, T_200, t200_expire, pri, tei);
+
+		} else {
+			if (pri->debug & PRI_DEBUG_Q921_STATE) 
+				pri_message("-- Timeout occured, restarting PRI\n");
+
+			pri->state = Q921_LINK_CONNECTION_RELEASED;
+
+			pri->t200_timer[teio] = 0;
+			// sowas wie q921_send_disc(pri,tei)
+			// XXX i need some attention here...
+			//     q921_dchannel_down(pri);
+			//     q921_start(pri, 1);
+			//     pri->schedev = 1;
 		}
-         if (pri->debug & PRI_DEBUG_Q921_STATE) 
-               pri_message("-- Rescheduling retransmission (%d)\n", pri->retrans[teio]);
-         pri->t200_timer[teio] = pri_schedule_event2(pri, T_200, t200_expire, pri, tei);
-      } else {
-         if (pri->debug & PRI_DEBUG_Q921_STATE) 
-               pri_message("-- Timeout occured, restarting PRI\n");
-    	pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
-    	pri->t200_timer[teio] = 0;
-         q921_dchannel_down(pri, tei);
-         q921_start(pri, 1, tei);
-         pri->schedev = 1;
-      }
+
 	} else if (pri->solicitfbit[teio]) {
          if (pri->debug & PRI_DEBUG_Q921_STATE)
             pri_message("-- Retrying poll with f-bit\n");
@@ -745,8 +771,8 @@
         		pri->schedev = 1; 
 		}
 	} else {
-		pri_error("T200 counter expired, nothing to send...\n");
-	   	pri->t200_timer[teio] = 0;
+		pri_error("T200 counter expired but nothing in queue to send...\n");
+		pri->t200_timer[teio] = 0;
 	}
 }
 
@@ -797,6 +823,13 @@
 	q921_frame *f, *prev=NULL;
 	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_RELEASED) {
+		pri_message("D-Channel down, bringing it up\n");
+
+		q921_send_sabme(pri, 1, pri->tei);
+	}
+
 	for (f=pri->txqueue[teio]; f; f = f->next) prev = f;
 	f = malloc(sizeof(q921_frame) + len + 2);
 	if (f) {
@@ -856,36 +889,40 @@
 			prev->next = f;
 		else
 			pri->txqueue[teio] = f;
-		/* Immediately transmit unless we're in a recovery state, or the window
-		   size is too big */
-// XXXXXX think about this...
-//		if (!pri->retrans[teio] && !pri->busy[teio]) {
-		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++;
+
+		if(pri->q921_state[teio] == Q921_LINK_CONNECTION_ESTABLISHED) {
+			/* Immediately transmit unless we're in a recovery state, or the window
+			   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)
+						pri_message("Delaying transmission of %d, window is %d/%d long\n", 
+							f->h.n_s, pri->windowlen[teio], pri->window[teio]);
+				}
+			}
+			if (pri->t203_timer[teio]) {
+				if (pri->debug & PRI_DEBUG_Q921_STATE)
+					pri_message("Stopping T_203 timer\n");
+				pri_schedule_del(pri, pri->t203_timer[teio]);
+				pri->t203_timer[teio] = 0;
+			}
+			if (!pri->t200_timer[teio]) {
+				if (pri->debug & PRI_DEBUG_Q921_STATE)
+					pri_message("Starting T_200 timer\n");
+				pri->t200_timer[teio] = pri_schedule_event2(pri, T_200, t200_expire, pri, tei);
 			} else {
 				if (pri->debug & PRI_DEBUG_Q921_STATE)
-					pri_message("Delaying transmission of %d, window is %d/%d long\n", 
-						f->h.n_s, pri->windowlen[teio], pri->window[teio]);
+					pri_message("T_200 timer already going (%d)\n", pri->t200_timer[teio]);
 			}
+		} else {
+			pri_message("L2 still down, delaying transmission\n");
 		}
-		if (pri->t203_timer[teio]) {
-			if (pri->debug & PRI_DEBUG_Q921_STATE)
-				pri_message("Stopping T_203 timer\n");
-			pri_schedule_del(pri, pri->t203_timer[teio]);
-			pri->t203_timer[teio] = 0;
-		}
-		if (!pri->t200_timer[teio]) {
-			if (pri->debug & PRI_DEBUG_Q921_STATE)
-				pri_message("Starting T_200 timer\n");
-			pri->t200_timer[teio] = pri_schedule_event2(pri, T_200, t200_expire, pri, tei);
-		} else
-			if (pri->debug & PRI_DEBUG_Q921_STATE)
-				pri_message("T_200 timer already going (%d)\n", pri->t200_timer[teio]);
-		
-	} else {
+
+		} else {
 		pri_error("!! Out of memory for Q.921 transmit\n");
 		return -1;
 	}
@@ -1095,9 +1132,6 @@
 	int teio=tei - Q921_TEI_BASE;
 	if (((teio < 0) || (teio > Q921_MAX_TEIS)) || (pri->localtype != BRI_NETWORK_PTMP)) { teio=0; }
 
-	/* Reset counters, etc */
-	q921_reset(pri, tei);
-	
 	/* Stop any SABME retransmissions */
 	if (pri->sabme_timer[teio]) {
 	    pri_schedule_del(pri, pri->sabme_timer[teio]);
@@ -1117,9 +1151,23 @@
 
 	/* Start the T203 timer */
 	pri->t203_timer[teio] = pri_schedule_event2(pri, T_203, t203_expire, pri, tei);
+
+	/* The flush pending I-frames */
+	q921_flush_txqueue(pri,tei);
 	
 	/* Report event that D-Channel is now up */
-        pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
+
+	if (pri->spoofing_state &&
+	   (pri->localtype == BRI_NETWORK ||
+	    pri->localtype == BRI_NETWORK_PTMP ||
+	    pri->localtype == BRI_CPE ||
+	    pri->localtype == BRI_CPE_PTMP))
+	        pri->ev.gen.e = PRI_EVENT_DCHAN_REALLY_UP;
+	else {
+		pri->spoofing_state = 1;
+	        pri->ev.gen.e = PRI_EVENT_DCHAN_UP;
+	}
+
         pri->ev.gen.tei = tei;
         return &pri->ev;
 }
@@ -1142,7 +1190,15 @@
 		pri->t203_timer[teio] = 0;
 	    }
 	}
-	pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
+
+	if (pri->localtype == BRI_NETWORK ||
+	    pri->localtype == BRI_NETWORK_PTMP ||
+	    pri->localtype == BRI_CPE ||
+	    pri->localtype == BRI_CPE_PTMP)
+	        pri->ev.gen.e = PRI_EVENT_DCHAN_REALLY_DOWN;
+	else
+	        pri->ev.gen.e = PRI_EVENT_DCHAN_DOWN;
+
 	pri->ev.gen.tei = tei;
 	return &pri->ev;	
 }
@@ -1171,6 +1227,7 @@
 	// xxx HMMM?
 	pri->busy[teio] = 0;
 	pri->solicitfbit[teio] = 0;
+
 	pri->q921_state[teio] = Q921_LINK_CONNECTION_RELEASED;
 	pri->retrans[teio] = 0;
 	pri->sentrej[teio] = 0;
@@ -1436,8 +1493,6 @@
 			q921_send_ua(pri, h->u.p_f, h->h.tei);
 			ev = q921_dchannel_down(pri, h->h.tei);
 			if ((pri->localtype == BRI_CPE_PTMP) || (pri->localtype == BRI_CPE)) {
-			    // keep layer 2 up
-			    q921_send_sabme(pri, 1, pri->tei);
 			    if (pri->t203_timer[teio])
 				pri_schedule_del(pri, pri->t203_timer[teio]);
 			    pri->t203_timer[teio] = 0;
