# Translate the D channels to a standard channel data.
# The HFC chipset provides us the D channel as data, but
# Zaptel expects it as a standard channel with 1000 samples
# per second.

Index: dahdi-linux-2.5.0/include/dahdi/kernel.h
===================================================================
--- dahdi-linux-2.5.0.orig/include/dahdi/kernel.h	2011-06-29 18:32:40.000000000 +0300
+++ dahdi-linux-2.5.0/include/dahdi/kernel.h	2011-08-15 14:14:26.000000000 +0300
@@ -413,6 +413,13 @@
 	int statcount;
 	int lastnumbufs;
 #endif
+#ifdef CONFIG_DAHDI_BRI_DCHANS
+	int bytes2receive;
+	int maxbytes2transmit; /* size of the tx buffer in the card driver */
+	int bytes2transmit;
+	int eofrx;
+	int eoftx;
+#endif
 	spinlock_t lock;
 	char name[40];
 	/* Specified by DAHDI */
@@ -723,6 +730,9 @@
 	DAHDI_FLAGBIT_TXUNDERRUN = 22,	/*!< Transmit underrun condition */
 	DAHDI_FLAGBIT_RXOVERRUN = 23,	/*!< Receive overrun condition */
 	DAHDI_FLAGBIT_DEVFILE	= 25,	/*!< Channel has a sysfs dev file */
+#if defined(CONFIG_DAHDI_BRI_DCHANS)
+	DAHDI_FLAGBIT_BRIDCHAN   = 26,	/*!< hardhdlc-like handling of the D channel */
+#endif
 };
 
 #ifdef CONFIG_DAHDI_NET
@@ -789,6 +799,7 @@
 #define DAHDI_FLAG_BUFEVENTS	DAHDI_FLAG(BUFEVENTS)
 #define DAHDI_FLAG_TXUNDERRUN	DAHDI_FLAG(TXUNDERRUN)
 #define DAHDI_FLAG_RXOVERRUN	DAHDI_FLAG(RXOVERRUN)
+#define DAHDI_FLAG_BRIDCHAN	DAHDI_FLAG(BRIDCHAN)
 
 struct file;
 
Index: dahdi-linux-2.5.0/include/dahdi/dahdi_config.h
===================================================================
--- dahdi-linux-2.5.0.orig/include/dahdi/dahdi_config.h	2011-01-05 17:52:03.000000000 +0200
+++ dahdi-linux-2.5.0/include/dahdi/dahdi_config.h	2011-08-15 14:13:01.000000000 +0300
@@ -195,4 +195,10 @@
  */
 /* #define CONFIG_DAHDI_MIRROR */
 
+/*
+ * Uncomment the following for BRI D channels
+ *
+ */
+#define CONFIG_DAHDI_BRI_DCHANS
+
 #endif
Index: dahdi-linux-2.5.0/drivers/dahdi/dahdi-base.c
===================================================================
--- dahdi-linux-2.5.0.orig/drivers/dahdi/dahdi-base.c	2011-07-21 19:26:31.000000000 +0300
+++ dahdi-linux-2.5.0/drivers/dahdi/dahdi-base.c	2011-08-15 14:13:01.000000000 +0300
@@ -7224,11 +7224,40 @@
 					*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
 				}
 				bytes -= left;
+#ifdef CONFIG_DAHDI_BRI_DCHANS
+			} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+			    /*
+			     * Let's get this right, we want to transmit complete frames only.
+			     * The card driver will do the dirty HDLC work for us.
+			     * txb (transmit buffer) is supposed to be big enough to store one frame
+			     * we will make this as big as the D fifo (1KB or 2KB)
+			     */
+
+			    /* there are 'left' bytes in the user buffer left to transmit */
+			    left = ms->writen[ms->outwritebuf] - ms->writeidx[ms->outwritebuf] - 2;
+			    if (left > ms->maxbytes2transmit) {
+				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], ms->maxbytes2transmit);
+				ms->writeidx[ms->outwritebuf] += ms->maxbytes2transmit;
+				txb += ms->maxbytes2transmit;
+				ms->bytes2transmit = ms->maxbytes2transmit;
+				ms->eoftx = 0;
+			    } else {
+				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
+				ms->writeidx[ms->outwritebuf] += left + 2;
+				txb += left + 2;
+				ms->bytes2transmit = left;
+				ms->eoftx = 1;
+			    }
+			    bytes = 0;
+#endif
 			} else {
 				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
 				ms->writeidx[ms->outwritebuf]+=left;
 				txb += left;
 				bytes -= left;
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+				ms->bytes2transmit=DAHDI_CHUNKSIZE;
+#endif
 			}
 			/* Check buffer status */
 			if (ms->writeidx[ms->outwritebuf] >= ms->writen[ms->outwritebuf]) {
@@ -7285,6 +7314,17 @@
 				/* Transmit a flag if this is an HDLC channel */
 				if (ms->flags & DAHDI_FLAG_HDLC)
 					fasthdlc_tx_frame_nocheck(&ms->txhdlc);
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+				if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+			//	    if (ms->bytes2transmit > 0) {
+					// txb += 2;
+					// ms->bytes2transmit -= 2;
+					bytes=0;
+					ms->eoftx = 1;
+//					printk(KERN_CRIT "zaptel EOF(%d) bytes2transmit %d\n",ms->eoftx,ms->bytes2transmit);
+			//	    }
+				}
+#endif
 #ifdef CONFIG_DAHDI_NET
 				if (dahdi_have_netdev(ms))
 					netif_wake_queue(chan_to_netdev(ms));
@@ -7346,6 +7386,12 @@
 			}
 			needtxunderrun += bytes;
 			bytes = 0;
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+		} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+		    ms->bytes2transmit = 0;
+		    ms->eoftx = 0;
+		    bytes = 0;
+#endif
 		} else {
 			memset(txb, DAHDI_LIN2X(0, ms), bytes);	/* Lastly we use silence on telephony channels */
 			needtxunderrun += bytes;
@@ -8267,6 +8313,14 @@
 	int res;
 	int left, x;
 
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+	if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+	    bytes = ms->bytes2receive;
+	    if (bytes < 1) return;
+//	    printk(KERN_CRIT "bytes2receive %d\n",ms->bytes2receive);
+	}
+#endif
+
 	while(bytes) {
 #if defined(CONFIG_DAHDI_NET)  || defined(CONFIG_DAHDI_PPP)
 		skb = NULL;
@@ -8324,6 +8378,19 @@
 						}
 					}
 				}
+#ifdef CONFIG_DAHDI_BRI_DCHANS
+			} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+			    memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
+			    rxb += left;
+			    ms->readidx[ms->inreadbuf] += left;
+			    bytes -= left;
+			    if (ms->eofrx == 1) {
+				eof=1;
+			    }
+//			    printk(KERN_CRIT "receiving %d bytes\n",ms->bytes2receive);
+			    ms->bytes2receive = 0;
+			    ms->eofrx = 0;
+#endif
 			} else {
 				/* Not HDLC */
 				memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
