Index: zaptel.c =================================================================== RCS file: /usr/cvsroot/zaptel/zaptel.c,v retrieving revision 1.95.2.1 diff -u -r1.95.2.1 zaptel.c --- zaptel.c 6 Oct 2004 22:11:41 -0000 1.95.2.1 +++ zaptel.c 2 Nov 2004 10:59:16 -0000 @@ -703,6 +703,20 @@ unsigned char *newbuf, *oldbuf; unsigned long flags; int x; + + /* Allocate history buffer, or not. This probably shouldn't + * be here, but it's convenient */ + if(!j) + { + if(ss->history) kfree(ss->history); + ss->history = NULL; + } + else + { + if(!ss->history) ss->history=kmalloc(ZT_HISTORY_BUF_LEN, GFP_KERNEL); + } + ss->historypos=0; + /* Check numbufs */ if (numbufs < 2) numbufs = 2; @@ -3856,11 +3870,12 @@ { struct zt_chan *chan = chans[unit]; unsigned long flags; - int j, rv; + int j, k1, k2, rv; int ret; int oldconf; void *rxgain=NULL; echo_can_state_t *ec, *tec; + struct zt_history hist; if (!chan) return -ENOSYS; @@ -4186,6 +4201,29 @@ return -EINVAL; break; #endif + case ZT_GET_HISTORY: + if (copy_from_user(&hist,(struct zt_history *) data,sizeof(hist))) + return -EIO; + + if (!(chan->flags & ZT_FLAG_AUDIO)) return (-EINVAL); + if (!chan->history) return -EINVAL; + j=hist.len; + k1=ZT_HISTORY_BUF_LEN-chan->historypos; + k2=chan->historypos; + if(j>0 && k1>0) + { + if (copy_to_user(hist.buf,chan->history+chan->historypos,min(j,k1))) + return -EIO; + j-=min(j,k1); + } + if(j>0 && k2>0) + { + if (copy_to_user(hist.buf+k1,chan->history,min(j,k2))) + return -EIO; + j-=min(j,k2); + } + /* Probably should assert j==0 here */ + break; default: return zt_chanandpseudo_ioctl(inode, file, cmd, data, unit); } @@ -5371,6 +5409,15 @@ if (!(ms->flags & ZT_FLAG_PSEUDO)) { memcpy(ms->putlin, putlin, ZT_CHUNKSIZE * sizeof(short)); memcpy(ms->putraw, rxb, ZT_CHUNKSIZE); + } + + /* Store in the history buffer */ + if(ms->history) + { + memcpy(ms->history+ms->historypos,rxb,ZT_CHUNKSIZE); + ms->historypos+=ZT_CHUNKSIZE; + if(ms->historypos >= ZT_HISTORY_BUF_LEN) + ms->historypos=0; } /* Take the rxc, twiddle it for conferencing if appropriate and put it Index: zaptel.h =================================================================== RCS file: /usr/cvsroot/zaptel/zaptel.h,v retrieving revision 1.38 diff -u -r1.38 zaptel.h --- zaptel.h 27 Sep 2004 19:50:03 -0000 1.38 +++ zaptel.h 2 Nov 2004 10:59:17 -0000 @@ -137,6 +137,8 @@ #define ZT_MAX_NUM_BUFS 32 #define ZT_MAX_BUF_SPACE 32768 +#define ZT_HISTORY_BUF_LEN 16384 /* Count of ulaw samples */ + #define ZT_DEFAULT_BLOCKSIZE 1024 #define ZT_DEFAULT_MTR_MRU 2048 @@ -277,6 +279,11 @@ int reserved[4]; /* Reserved for future expansion -- always set to 0 */ } ZT_DIAL_PARAMS; +typedef struct zt_history +{ + unsigned char *buf; /* Sample buffer */ + int len; /* Length of buffer, in bytes */ +} ZT_HISTORY; typedef struct zt_dynamic_span { char driver[20]; /* Which low-level driver to use */ @@ -584,6 +591,11 @@ #define ZT_TIMERPONG _IOW (ZT_CODE, 53, int) /* + * Return history buffer + */ +#define ZT_GET_HISTORY _IOR(ZT_CODE, 54, struct zt_history) + +/* * Set/get signalling freeze */ #define ZT_SIGFREEZE _IOW (ZT_CODE, 54, int) @@ -989,6 +1001,10 @@ wait_queue_head_t writebufq; /* write wait queue */ int blocksize; /* Block size */ + + + u_char *history; /* History buffer, for pre-ring caller ID (ZT_HISTORY_BUF_LEN) */ + u_short historypos; /* Current position within buffer */ int eventinidx; /* out index in event buf (circular) */ int eventoutidx; /* in index in event buf (circular) */