# 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. --- a/include/dahdi/kernel.h +++ b/include/dahdi/kernel.h @@ -132,6 +132,13 @@ struct dahdi_chan { int do_ppp_error; struct sk_buff_head ppp_rq; #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 */ @@ -462,6 +469,9 @@ enum { DAHDI_FLAGBIT_LOOPED = 18, /*!< Loopback the receive data from the channel to the transmit */ DAHDI_FLAGBIT_MTP2 = 19, /*!< Repeats last message in buffer and also discards repeating messages sent to us */ DAHDI_FLAGBIT_HDLC56 = 20, /*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K */ +#if defined(CONFIG_DAHDI_BRI_DCHANS) + DAHDI_FLAGBIT_BRIDCHAN = 21, /*!< hardhdlc-like handling of the D channel */ +#endif }; /* map flagbits to flag masks */ @@ -500,6 +510,7 @@ enum { #define DAHDI_FLAG_LOOPED DAHDI_FLAG(LOOPED) #define DAHDI_FLAG_MTP2 DAHDI_FLAG(MTP2) #define DAHDI_FLAG_HDLC56 DAHDI_FLAG(HDLC56) +#define DAHDI_FLAG_BRIDCHAN DAHDI_FLAG(BRIDCHAN) struct dahdi_span { spinlock_t lock; --- a/include/dahdi/dahdi_config.h +++ b/include/dahdi/dahdi_config.h @@ -174,4 +174,10 @@ */ /* #define OPTIMIZE_CHANMUTE */ +/* + * Uncomment the following for BRI D channels + * + */ +#define CONFIG_DAHDI_BRI_DCHANS + #endif --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -5907,11 +5907,40 @@ static inline void __dahdi_getbuf_chunk( *(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]) { @@ -5968,6 +5997,17 @@ out in the later versions, and is put ba /* 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 (ms->flags & DAHDI_FLAG_NETDEV) netif_wake_queue(ztchan_to_dev(ms)); @@ -6028,6 +6068,12 @@ out in the later versions, and is put ba memset(txb, 0xFF, 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 */ bytes = 0; @@ -6840,6 +6886,14 @@ static inline void __putbuf_chunk(struct 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; @@ -6897,6 +6951,19 @@ static inline void __putbuf_chunk(struct } } } +#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);