hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
 * Audio support data for ISDN4Linux.
 *
 * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */
 
#define DEBUG_DSP_CTRL        0x0001
#define DEBUG_DSP_CORE        0x0002
#define DEBUG_DSP_DTMF        0x0004
#define DEBUG_DSP_CMX        0x0010
#define DEBUG_DSP_TONE        0x0020
#define DEBUG_DSP_BLOWFISH    0x0040
#define DEBUG_DSP_DELAY        0x0100
#define DEBUG_DSP_CLOCK        0x0200
#define DEBUG_DSP_DTMFCOEFF    0x8000 /* heavy output */
 
/* options may be:
 *
 * bit 0 = use ulaw instead of alaw
 * bit 1 = enable hfc hardware acceleration for all channels
 *
 */
#define DSP_OPT_ULAW        (1 << 0)
#define DSP_OPT_NOHARDWARE    (1 << 1)
 
#include <linux/timer.h>
#include <linux/workqueue.h>
 
#include "dsp_ecdis.h"
 
extern int dsp_options;
extern int dsp_debug;
extern int dsp_poll;
extern int dsp_tics;
extern spinlock_t dsp_lock;
extern struct work_struct dsp_workq;
extern u32 dsp_poll_diff; /* calculated fix-comma corrected poll value */
 
/***************
 * audio stuff *
 ***************/
 
extern s32 dsp_audio_alaw_to_s32[256];
extern s32 dsp_audio_ulaw_to_s32[256];
extern s32 *dsp_audio_law_to_s32;
extern u8 dsp_audio_s16_to_law[65536];
extern u8 dsp_audio_alaw_to_ulaw[256];
extern u8 dsp_audio_mix_law[65536];
extern u8 dsp_audio_seven2law[128];
extern u8 dsp_audio_law2seven[256];
extern void dsp_audio_generate_law_tables(void);
extern void dsp_audio_generate_s2law_table(void);
extern void dsp_audio_generate_seven(void);
extern void dsp_audio_generate_mix_table(void);
extern void dsp_audio_generate_ulaw_samples(void);
extern void dsp_audio_generate_volume_changes(void);
extern u8 dsp_silence;
 
 
/*************
 * cmx stuff *
 *************/
 
#define MAX_POLL    256    /* maximum number of send-chunks */
 
#define CMX_BUFF_SIZE    0x8000    /* must be 2**n (0x1000 about 1/2 second) */
#define CMX_BUFF_HALF    0x4000    /* CMX_BUFF_SIZE / 2 */
#define CMX_BUFF_MASK    0x7fff    /* CMX_BUFF_SIZE - 1 */
 
/* how many seconds will we check the lowest delay until the jitter buffer
   is reduced by that delay */
#define MAX_SECONDS_JITTER_CHECK 5
 
extern struct timer_list dsp_spl_tl;
 
/* the datatype need to match jiffies datatype */
extern unsigned long dsp_spl_jiffies;
 
/* the structure of conferences:
 *
 * each conference has a unique number, given by user space.
 * the conferences are linked in a chain.
 * each conference has members linked in a chain.
 * each dsplayer points to a member, each member points to a dsplayer.
 */
 
/* all members within a conference (this is linked 1:1 with the dsp) */
struct dsp;
struct dsp_conf_member {
   struct list_head    list;
   struct dsp        *dsp;
};
 
/* the list of all conferences */
struct dsp_conf {
   struct list_head    list;
   u32            id;
   /* all cmx stacks with the same ID are
      connected */
   struct list_head    mlist;
   int            software; /* conf is processed by software */
   int            hardware; /* conf is processed by hardware */
   /* note: if both unset, has only one member */
};
 
 
/**************
 * DTMF stuff *
 **************/
 
#define DSP_DTMF_NPOINTS 102
 
#define ECHOCAN_BUFF_SIZE 0x400 /* must be 2**n */
#define ECHOCAN_BUFF_MASK 0x3ff /* -1 */
 
struct dsp_dtmf {
   int        enable; /* dtmf is enabled */
   int        treshold; /* above this is dtmf (square of) */
   int        software; /* dtmf uses software decoding */
   int        hardware; /* dtmf uses hardware decoding */
   int        size; /* number of bytes in buffer */
   signed short    buffer[DSP_DTMF_NPOINTS];
   /* buffers one full dtmf frame */
   u8        lastwhat, lastdigit;
   int        count;
   u8        digits[16]; /* dtmf result */
};
 
 
/******************
 * pipeline stuff *
 ******************/
struct dsp_pipeline {
   rwlock_t  lock;
   struct list_head list;
   int inuse;
};
 
/***************
 * tones stuff *
 ***************/
 
struct dsp_tone {
   int        software; /* tones are generated by software */
   int        hardware; /* tones are generated by hardware */
   int        tone;
   void        *pattern;
   int        count;
   int        index;
   struct timer_list tl;
};
 
/***************
 * echo stuff *
 ***************/
 
struct dsp_echo {
   int        software; /* echo is generated by software */
   int        hardware; /* echo is generated by hardware */
};
 
/*****************
 * general stuff *
 *****************/
 
struct dsp {
   struct list_head list;
   struct mISDNchannel    ch;
   struct mISDNchannel    *up;
   unsigned char    name[64];
   int        b_active;
   struct dsp_echo    echo;
   int        rx_disabled; /* what the user wants */
   int        rx_is_off; /* what the card is */
   int        tx_mix;
   struct dsp_tone    tone;
   struct dsp_dtmf    dtmf;
   int        tx_volume, rx_volume;
 
   /* queue for sending frames */
   struct work_struct    workq;
   struct sk_buff_head    sendq;
   int        hdlc;    /* if mode is hdlc */
   int        data_pending;    /* currently an unconfirmed frame */
 
   /* conference stuff */
   u32        conf_id;
   struct dsp_conf    *conf;
   struct dsp_conf_member
   *member;
 
   /* buffer stuff */
   int        rx_W; /* current write pos for data without timestamp */
   int        rx_R; /* current read pos for transmit clock */
   int        rx_init; /* if set, pointers will be adjusted first */
   int        tx_W; /* current write pos for transmit data */
   int        tx_R; /* current read pos for transmit clock */
   int        rx_delay[MAX_SECONDS_JITTER_CHECK];
   int        tx_delay[MAX_SECONDS_JITTER_CHECK];
   u8        tx_buff[CMX_BUFF_SIZE];
   u8        rx_buff[CMX_BUFF_SIZE];
   int        last_tx; /* if set, we transmitted last poll interval */
   int        cmx_delay; /* initial delay of buffers,
                     or 0 for dynamic jitter buffer */
   int        tx_dejitter; /* if set, dejitter tx buffer */
   int        tx_data; /* enables tx-data of CMX to upper layer */
 
   /* hardware stuff */
   struct dsp_features features;
   int        features_rx_off; /* set if rx_off is featured */
   int        features_fill_empty; /* set if fill_empty is featured */
   int        pcm_slot_rx; /* current PCM slot (or -1) */
   int        pcm_bank_rx;
   int        pcm_slot_tx;
   int        pcm_bank_tx;
   int        hfc_conf; /* unique id of current conference (or -1) */
 
   /* encryption stuff */
   int        bf_enable;
   u32        bf_p[18];
   u32        bf_s[1024];
   int        bf_crypt_pos;
   u8        bf_data_in[9];
   u8        bf_crypt_out[9];
   int        bf_decrypt_in_pos;
   int        bf_decrypt_out_pos;
   u8        bf_crypt_inring[16];
   u8        bf_data_out[9];
   int        bf_sync;
 
   struct dsp_pipeline
   pipeline;
};
 
/* functions */
 
extern void dsp_change_volume(struct sk_buff *skb, int volume);
 
extern struct list_head dsp_ilist;
extern struct list_head conf_ilist;
extern void dsp_cmx_debug(struct dsp *dsp);
extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp);
extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id);
extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb);
extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb);
extern void dsp_cmx_send(struct timer_list *arg);
extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb);
extern int dsp_cmx_del_conf_member(struct dsp *dsp);
extern int dsp_cmx_del_conf(struct dsp_conf *conf);
 
extern void dsp_dtmf_goertzel_init(struct dsp *dsp);
extern void dsp_dtmf_hardware(struct dsp *dsp);
extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len,
                   int fmt);
 
extern int dsp_tone(struct dsp *dsp, int tone);
extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len);
extern void dsp_tone_timeout(struct timer_list *t);
 
extern void dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len);
extern void dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len);
extern int dsp_bf_init(struct dsp *dsp, const u8 *key, unsigned int keylen);
extern void dsp_bf_cleanup(struct dsp *dsp);
 
extern int  dsp_pipeline_module_init(void);
extern void dsp_pipeline_module_exit(void);
extern int  dsp_pipeline_init(struct dsp_pipeline *pipeline);
extern void dsp_pipeline_destroy(struct dsp_pipeline *pipeline);
extern int  dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
                   int len);
extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
                   int len, unsigned int txlen);