1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
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) */
|