Removed obsolete logging code
[lcr.git] / mISDN.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN port abstraction for dss1                                           **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13 #include "myisdn.h"
14 #include <mISDN/q931.h>
15
16 #undef offsetof
17 #ifdef __compiler_offsetof
18 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
19 #else
20 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
21 #endif
22
23 #ifndef container_of
24 #define container_of(ptr, type, member) ({                      \
25         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
26         (type *)( (char *)__mptr - offsetof(type,member) );})
27 #endif
28
29 // timeouts if activating/deactivating response from mISDN got lost
30 #define B_TIMER_ACTIVATING 1 // seconds
31 #define B_TIMER_DEACTIVATING 1 // seconds
32
33 /* list of mISDN ports */
34 struct mISDNport *mISDNport_first;
35
36 /* noise randomizer */
37 unsigned char mISDN_rand[256];
38 int mISDN_rand_count = 0;
39
40 #ifdef OLD_MT_ASSIGN
41 unsigned int mt_assign_pid = ~0;
42 #endif
43
44 int mISDNsocket = -1;
45 static int upqueue_pipe[2];
46 static struct lcr_fd upqueue_fd;
47 int upqueue_avail = 0;
48
49 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
50 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
51
52 static int my_mISDNlib_debug(const char *file, int line, const char *func, int level, const char *fmt, va_list va)
53 {
54         int ret = 0;
55
56         if (debug_fp > 0)
57                 ret = vfprintf(debug_fp, fmt, va);
58         return ret;
59 }
60
61 static struct mi_ext_fn_s myfn;
62
63 int mISDN_initialize(void)
64 {
65         char filename[256];
66         int ver;
67
68         /* try to open raw socket to check kernel */
69         mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
70         if (mISDNsocket < 0) {
71                 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
72                 return(-1);
73         }
74
75         /* init mlayer3 */
76         // set debug printout function
77         myfn.prt_debug = my_mISDNlib_debug;
78
79         ver = init_layer3(4, &myfn); // buffer of 4
80
81         /* open debug, if enabled and not only stack debugging */
82         if (options.deb) {
83                 SPRINT(filename, "%s/debug.log", LOG_DIR);
84                 debug_fp = fopen(filename, "a");
85         }
86
87         if (options.deb & DEBUG_STACK)
88                 mISDN_set_debug_level(0xfffffeff);
89         else
90                 mISDN_set_debug_level(0);
91
92         if (pipe(upqueue_pipe) < 0)
93                 FATAL("Failed to open pipe\n");
94         memset(&upqueue_fd, 0, sizeof(upqueue_fd));
95         upqueue_fd.fd = upqueue_pipe[0];
96         register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
97
98         return(0);
99 }
100
101 void mISDN_deinitialize(void)
102 {
103         cleanup_layer3();
104
105         if (debug_fp)
106                 fclose(debug_fp);
107         debug_fp = NULL;
108
109         if (mISDNsocket > -1)
110                 close(mISDNsocket);
111
112         if (upqueue_fd.inuse) {
113                 unregister_fd(&upqueue_fd);
114                 close(upqueue_pipe[0]);
115                 close(upqueue_pipe[1]);
116         }
117         upqueue_avail = 0;
118 }
119
120 int load_timer(struct lcr_timer *timer, void *instance, int index);
121
122 /*
123  * constructor
124  */
125 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, struct interface *interface, int channel, int exclusive, int mode) : Port(type, portname, settings, interface)
126 {
127         p_m_mISDNport = mISDNport;
128         p_m_portnum = mISDNport->portnum;
129         p_m_b_index = -1;
130         p_m_b_channel = 0;
131         p_m_b_exclusive = 0;
132         p_m_b_reserve = 0;
133         p_m_b_mode = mode;
134         p_m_hold = 0;
135         p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
136         p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
137         p_m_conf = 0;
138         p_m_mute = 0;
139         p_m_txdata = 0;
140         p_m_delay = 0;
141         p_m_tx_dejitter = 0;
142         p_m_preload = ISDN_LOAD;
143         p_m_disable_dejitter = 0;
144         p_m_echo = 0;
145         p_m_tone = 0;
146         p_m_rxoff = 0;
147         p_m_inband_send_on = 0;
148         p_m_inband_receive_on = 0;
149         p_m_dtmf = !mISDNport->ifport->nodtmf;
150         memset(&p_m_timeout, 0, sizeof(p_m_timeout));
151         add_timer(&p_m_timeout, mISDN_timeout, this, 0);
152         SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
153         
154         /* audio */
155         memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
156         add_timer(&p_m_loadtimer, load_timer, this, 0);
157         p_m_load = 0;
158         p_m_last_tv_sec = 0;
159
160         /* crypt */
161         p_m_crypt = 0;
162         p_m_crypt_listen = 0;
163         p_m_crypt_msg_loops = 0;
164         p_m_crypt_msg_loops = 0;
165         p_m_crypt_msg_len = 0;
166         p_m_crypt_msg[0] = '\0';
167         p_m_crypt_msg_current = 0;
168         p_m_crypt_key_len = 0;
169         p_m_crypt_listen = 0;
170         p_m_crypt_listen_state = 0;
171         p_m_crypt_listen_len = 0;
172         p_m_crypt_listen_msg[0] = '\0';
173         p_m_crypt_listen_crc = 0;
174         if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
175                 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
176                 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
177                 p_m_crypt = 1;
178         }
179
180         /* if any channel requested by constructor */
181         if (channel == CHANNEL_ANY) {
182                 /* reserve channel */
183                 p_m_b_reserve = 1;
184                 mISDNport->b_reserved++;
185         }
186
187         /* reserve channel */
188         if (channel > 0) // only if constructor was called with a channel resevation
189                 seize_bchannel(channel, exclusive);
190
191         /* we increase the number of objects: */
192         mISDNport->use++;
193         PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
194 //inband_receive_on();
195 }
196
197
198 /*
199  * destructor
200  */
201 PmISDN::~PmISDN()
202 {
203         struct lcr_msg *message;
204
205         del_timer(&p_m_timeout);
206         del_timer(&p_m_loadtimer);
207
208         /* remove bchannel relation */
209         drop_bchannel();
210
211         /* release epoint */
212         while (p_epointlist) {
213                 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
214                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
215                 message->param.disconnectinfo.cause = 16;
216                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
217                 message_put(message);
218                 /* remove from list */
219                 free_epointlist(p_epointlist);
220         }
221
222         /* we decrease the number of objects: */
223         p_m_mISDNport->use--;
224         PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
225 }
226
227
228 /*
229  * trace
230  */
231 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
232 {
233         /* init trace with given values */
234         start_trace(mISDNport?mISDNport->portnum:-1,
235                     (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
236                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
237                     port?port->p_dialinginfo.id:NULL,
238                     direction,
239                     CATEGORY_CH,
240                     port?port->p_serial:0,
241                     msgtext);
242 }
243
244
245 /*
246  * layer trace header
247  */
248 static struct isdn_message {
249         const char *name;
250         unsigned int value;
251 } isdn_message[] = {
252         {"PH_ACTIVATE", L1_ACTIVATE_REQ},
253         {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
254         {"DL_ESTABLISH", L2_ESTABLISH_REQ},
255         {"DL_RELEASE", L2_RELEASE_REQ},
256         {"UNKNOWN", L3_UNKNOWN_REQ},
257         {"MT_TIMEOUT", L3_TIMEOUT_REQ},
258         {"MT_SETUP", L3_SETUP_REQ},
259         {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
260         {"MT_PROCEEDING", L3_PROCEEDING_REQ},
261         {"MT_ALERTING", L3_ALERTING_REQ},
262         {"MT_CONNECT", L3_CONNECT_REQ},
263         {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
264         {"MT_DISCONNECT", L3_DISCONNECT_REQ},
265         {"MT_RELEASE", L3_RELEASE_REQ},
266         {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
267         {"MT_INFORMATION", L3_INFORMATION_REQ},
268         {"MT_PROGRESS", L3_PROGRESS_REQ},
269         {"MT_NOTIFY", L3_NOTIFY_REQ},
270         {"MT_SUSPEND", L3_SUSPEND_REQ},
271         {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
272         {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
273         {"MT_RESUME", L3_RESUME_REQ},
274         {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
275         {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
276         {"MT_HOLD", L3_HOLD_REQ},
277         {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
278         {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
279         {"MT_RETRIEVE", L3_RETRIEVE_REQ},
280         {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
281         {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
282         {"MT_FACILITY", L3_FACILITY_REQ},
283         {"MT_STATUS", L3_STATUS_REQ},
284         {"MT_RESTART", L3_RESTART_REQ},
285         {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
286         {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
287         {NULL, 0},
288 };
289 static const char *isdn_prim[4] = {
290         " REQUEST",
291         " CONFIRM",
292         " INDICATION",
293         " RESPONSE",
294 };
295 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
296 {
297         int i;
298         char msgtext[64];
299
300         SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
301         /* select message and primitive text */
302         i = 0;
303         while(isdn_message[i].name) {
304 //              if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
305                 if (isdn_message[i].value == (msg&0xffffff00)) {
306                         SCPY(msgtext, isdn_message[i].name);
307                         break;
308                 }
309                 i++;
310         }
311         SCAT(msgtext, isdn_prim[msg&0x00000003]);
312
313         /* add direction */
314         if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
315                 if (mISDNport) {
316                         if (mISDNport->ntmode) {
317                                 if (direction == DIRECTION_OUT)
318                                         SCAT(msgtext, " N->U");
319                                 else
320                                         SCAT(msgtext, " N<-U");
321                         } else {
322                                 if (direction == DIRECTION_OUT)
323                                         SCAT(msgtext, " U->N");
324                                 else
325                                         SCAT(msgtext, " U<-N");
326                         }
327                 }
328         }
329
330         /* init trace with given values */
331         start_trace(mISDNport?mISDNport->portnum:-1,
332                     mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
333                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
334                     port?port->p_dialinginfo.id:NULL,
335                     direction,
336                     CATEGORY_CH,
337                     port?port->p_serial:0,
338                     msgtext);
339 }
340
341
342 /*
343  * send control information to the channel (dsp-module)
344  */
345 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
346 {
347         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
348         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
349         unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
350         int ret;
351
352         if (sock < 0)
353                 return;
354
355         ctrl->prim = PH_CONTROL_REQ;
356         ctrl->id = 0;
357         *d++ = c1;
358         *d++ = c2;
359         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
360         if (ret <= 0)
361                 PERROR("Failed to send to socket %d\n", sock);
362         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
363         if (c1 == DSP_CONF_JOIN)
364                 add_trace(trace_name, NULL, "0x%08x", trace_value);
365         else
366                 add_trace(trace_name, NULL, "%d", trace_value);
367         end_trace();
368 }
369
370 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, const char *trace_name, int trace_value)
371 {
372         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
373         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
374         unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
375         int ret;
376
377         if (sock < 0)
378                 return;
379
380         ctrl->prim = PH_CONTROL_REQ;
381         ctrl->id = 0;
382         *d++ = c1;
383         memcpy(d, c2, c2_len);
384         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
385         if (ret <= 0)
386                 PERROR("Failed to send to socket %d\n", sock);
387         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
388         add_trace(trace_name, NULL, "%d", trace_value);
389         end_trace();
390 }
391
392 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
393
394 /*
395  * subfunction for bchannel_event
396  * create stack
397  */
398 static int _bchannel_create(struct mISDNport *mISDNport, int i)
399 {
400         int ret;
401         struct sockaddr_mISDN addr;
402
403         if (mISDNport->b_sock[i].inuse) {
404                 PERROR("Error: Socket already created for index %d\n", i);
405                 return(0);
406         }
407
408         /* open socket */
409 //#warning testing without DSP
410 //      mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
411         mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
412         if (mISDNport->b_sock[i].fd < 0) {
413                 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
414                 return(0);
415         }
416
417         /* register callback for read */
418         register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
419         
420         /* bind socket to bchannel */
421         addr.family = AF_ISDN;
422         addr.dev = mISDNport->portnum;
423         addr.channel = i+1+(i>=15);
424         ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
425         if (ret < 0) {
426                 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer (errno=%d). Did you load mISDN_dsp.ko?\n", i, errno);
427                 close(mISDNport->b_sock[i].fd);
428                 unregister_fd(&mISDNport->b_sock[i]);
429                 return(0);
430         }
431
432         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
433         add_trace("channel", NULL, "%d", i+1+(i>=15));
434         add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
435         end_trace();
436
437         return(1);
438 }
439
440
441 /*
442  * subfunction for bchannel_event
443  * activate / deactivate request
444  */
445 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
446 {
447         struct mISDNhead act;
448         int ret;
449
450         if (!mISDNport->b_sock[i].inuse)
451                 return;
452         act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ; 
453         act.id = 0;
454         ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
455         if (ret <= 0)
456                 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
457
458         /* trace */
459         chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
460         add_trace("channel", NULL, "%d", i+1+(i>=15));
461         if (timeout)
462                 add_trace("event", NULL, "timeout recovery");
463         end_trace();
464 }
465
466
467 /*
468  * subfunction for bchannel_event
469  * set features
470  */
471 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
472 {
473         struct PmISDN *port;
474         int handle, mode;
475
476         if (!mISDNport->b_sock[i].inuse)
477                 return;
478         handle = mISDNport->b_sock[i].fd;
479         port = mISDNport->b_port[i];
480         mode = mISDNport->b_mode[i];
481         if (!port) {
482                 PERROR("bchannel index i=%d not associated with a port object\n", i);
483                 return;
484         }
485
486         /* set dsp features */
487         if (port->p_m_txdata)
488                 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
489         if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
490                 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
491         if (port->p_m_tx_dejitter && mode == B_MODE_TRANSPARENT)
492                 ph_control(mISDNport, port, handle, DSP_TX_DEJITTER, port->p_m_tx_dejitter, "DSP-TX_DEJITTER", port->p_m_tx_dejitter);
493         if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
494                 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
495         if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
496                 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
497         if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
498                 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
499         if (port->p_m_conf && !port->p_m_mute)
500                 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
501         if (port->p_m_echo)
502                 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
503         if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
504                 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
505         if (port->p_m_rxoff)
506                 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
507 //      if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
508 //              ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
509         if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
510                 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
511         if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
512                 ph_control_block(mISDNport, port, handle, DSP_BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
513 }
514
515
516 void PmISDN::set_conf(int oldconf, int newconf)
517 {
518                 if (oldconf != newconf) {
519                         PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
520                         if (p_m_b_index > -1)
521                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
522                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, (newconf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, newconf, "DSP-CONF", newconf);
523                 } else
524                         PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
525 }
526
527
528 /*
529  * subfunction for bchannel_event
530  * destroy stack
531  */
532 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
533 {
534         if (!mISDNport->b_sock[i].inuse)
535                 return;
536         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
537         add_trace("channel", NULL, "%d", i+1+(i>=15));
538         add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
539         end_trace();
540         close(mISDNport->b_sock[i].fd);
541         unregister_fd(&mISDNport->b_sock[i]);
542 }
543
544
545 /*
546 bchannel procedure
547 ------------------
548
549 A bchannel goes through the following states in this order:
550
551 - B_STATE_IDLE
552 No one is using the bchannel.
553 It is available and not linked to Port class, nor reserved.
554
555 - B_STATE_ACTIVATING
556 The bchannel stack is created and an activation request is sent.
557 It MAY be linked to Port class, but already unlinked due to Port class removal.
558
559 - B_STATE_ACTIVE
560 The bchannel is active and cofigured to the Port class needs.
561 Also it is linked to a Port class, otherwhise it would be deactivated.
562
563 - B_STATE_DEACTIVATING
564 The bchannel is in deactivating state, due to deactivation request.
565 It may be linked to a Port class, that likes to reactivate it.
566
567 - B_STATE_IDLE
568 See above.
569 After deactivating bchannel, and if not used, the bchannel becomes idle again.
570
571 A bchannel can have the following events:
572
573 - B_EVENT_USE
574 A bchannel is required by a Port class.
575
576 - B_EVENT_ACTIVATED
577 The bchannel beomes active.
578
579 - B_EVENT_DROP
580 The bchannel is not required by Port class anymore
581
582 - B_EVENT_DEACTIVATED
583 The bchannel becomes inactive.
584
585 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
586
587 */
588
589 /*
590  * process bchannel events
591  * - mISDNport is a pointer to the port's structure
592  * - i is the index of the bchannel
593  * - event is the B_EVENT_* value
594  * - port is the PmISDN class pointer
595  */
596 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
597 {
598         class PmISDN *b_port = mISDNport->b_port[i];
599         int state = mISDNport->b_state[i];
600         int timer = -1; // no change
601         int p_m_tx_gain = 0;
602         int p_m_rx_gain = 0;
603         char *p_m_pipeline = NULL;
604         unsigned char *p_m_crypt_key = NULL;
605         int p_m_crypt_key_len = 0;
606         int p_m_crypt_key_type = 0;
607
608         if (b_port) {
609                 p_m_tx_gain = b_port->p_m_tx_gain;
610                 p_m_rx_gain = b_port->p_m_rx_gain;
611                 p_m_pipeline = b_port->p_m_pipeline;
612                 p_m_crypt_key = b_port->p_m_crypt_key;
613                 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
614                 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
615         }
616
617         switch(event) {
618                 case B_EVENT_USE:
619                 /* port must be linked in order to allow activation */
620                 if (!b_port)
621                         FATAL("bchannel must be linked to a Port class\n");
622                 switch(state) {
623                         case B_STATE_IDLE:
624                         /* create stack and send activation request */
625                         if (_bchannel_create(mISDNport, i)) {
626                                 _bchannel_activate(mISDNport, i, 1, 0);
627                                 state = B_STATE_ACTIVATING;
628                                 timer = B_TIMER_ACTIVATING;
629                         }
630                         break;
631
632                         case B_STATE_ACTIVATING:
633                         /* do nothing, because it is already activating */
634                         break;
635
636                         default:
637                         /* problems that might ocurr:
638                          * B_EVENT_USE is received when channel already in use.
639                          */
640                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
641                 }
642                 break;
643
644
645                 case B_EVENT_ACTIVATED:
646                 timer = 0;
647                 switch(state) {
648                         case B_STATE_ACTIVATING:
649                         if (b_port) {
650                                 /* bchannel is active and used by Port class, so we configure bchannel */
651                                 _bchannel_configure(mISDNport, i);
652                                 state = B_STATE_ACTIVE;
653                                 b_port->p_m_load = 0;
654                                 b_port->update_load();
655                         } else {
656                                 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
657                                 _bchannel_activate(mISDNport, i, 0, 0);
658                                 state = B_STATE_DEACTIVATING;
659                                 timer = B_TIMER_DEACTIVATING;
660                         }
661                         break;
662
663                         default:
664                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
665                 }
666                 break;
667
668                 case B_EVENT_DROP:
669                 if (!b_port)
670                         FATAL("bchannel must be linked to a Port class\n");
671                 switch(state) {
672                         case B_STATE_IDLE:
673                         /* bchannel is idle due to an error, so we do nothing */
674                         break;
675
676                         case B_STATE_ACTIVATING:
677                         /* do nothing because we must wait until bchanenl is active before deactivating */
678                         break;
679
680                         case B_STATE_ACTIVE:
681                         /* bchannel is active, so we deactivate */
682                         _bchannel_activate(mISDNport, i, 0, 0);
683                         state = B_STATE_DEACTIVATING;
684                         timer = B_TIMER_DEACTIVATING;
685                         break;
686
687                         case B_STATE_DEACTIVATING:
688                         /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
689                         break;
690
691                         default:
692                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
693                 }
694                 break;
695
696                 case B_EVENT_DEACTIVATED:
697                 timer = 0;
698                 switch(state) {
699                         case B_STATE_IDLE:
700                         /* ignore due to deactivation confirm after unloading */
701                         break;
702
703                         case B_STATE_DEACTIVATING:
704                         _bchannel_destroy(mISDNport, i);
705                         state = B_STATE_IDLE;
706                         if (b_port) {
707                                 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
708                                 if (_bchannel_create(mISDNport, i)) {
709                                         _bchannel_activate(mISDNport, i, 1, 0);
710                                         state = B_STATE_ACTIVATING;
711                                         timer = B_TIMER_ACTIVATING;
712                                 }
713                         }
714                         break;
715
716                         default:
717                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
718                 }
719                 break;
720
721                 case B_EVENT_TIMEOUT:
722                 timer = 0;
723                 switch(state) {
724                         case B_STATE_IDLE:
725                         /* ignore due to deactivation confirm after unloading */
726                         break;
727
728                         case B_STATE_ACTIVATING:
729                         _bchannel_activate(mISDNport, i, 1, 1);
730                         timer = B_TIMER_ACTIVATING;
731                         break;
732
733                         case B_STATE_DEACTIVATING:
734                         _bchannel_activate(mISDNport, i, 0, 1);
735                         timer = B_TIMER_DEACTIVATING;
736                         break;
737
738                         default:
739                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
740                 }
741                 break;
742
743                 default:
744                 PERROR("Illegal event %d, please correct.\n", event);
745         }
746
747         mISDNport->b_state[i] = state;
748         if (timer == 0)
749                 unsched_timer(&mISDNport->b_timer[i]);
750         else if (timer > 0)
751                 schedule_timer(&mISDNport->b_timer[i], timer, 0);
752 }
753
754
755
756
757 /*
758  * check for available channel and reserve+set it.
759  * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
760  * give exclusiv flag
761  * returns -(cause value) or x = channel x or 0 = no channel
762  * NOTE: no activation is done here
763  */
764 int PmISDN::seize_bchannel(int channel, int exclusive)
765 {
766         int i;
767
768         /* the channel is what we have */
769         if (p_m_b_channel == channel)
770                 return(channel);
771
772         /* if channel already in use, release it */
773         if (p_m_b_channel)
774                 drop_bchannel();
775
776         /* if CHANNEL_NO */
777         if (channel==CHANNEL_NO || channel==0)
778                 return(0);
779         
780         /* is channel in range ? */
781         if (channel==16
782          || (channel>p_m_mISDNport->b_num && channel<16)
783          || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
784                 return(-6); /* channel unacceptable */
785
786         /* request exclusive channel */
787         if (exclusive && channel>0) {
788                 i = channel-1-(channel>16);
789                 if (p_m_mISDNport->b_port[i])
790                         return(-44); /* requested channel not available */
791                 goto seize;
792         }
793
794         /* ask for channel */
795         if (channel>0) {
796                 i = channel-1-(channel>16);
797                 if (p_m_mISDNport->b_port[i] == NULL)
798                         goto seize;
799         }
800
801         /* search for channel */
802         i = 0;
803         while(i < p_m_mISDNport->b_num) {
804                 if (!p_m_mISDNport->b_port[i]) {
805                         channel = i+1+(i>=15);
806                         goto seize;
807                 }
808                 i++;
809         }
810         return(-34); /* no free channel */
811
812 seize:
813         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
814
815         /* link Port, set parameters */
816         p_m_mISDNport->b_port[i] = this;
817         p_m_b_index = i;
818         p_m_b_channel = channel;
819         p_m_b_exclusive = exclusive;
820         p_m_mISDNport->b_mode[i] = p_m_b_mode;
821
822         /* reserve channel */
823         if (!p_m_b_reserve) {
824                 p_m_b_reserve = 1;
825                 p_m_mISDNport->b_reserved++;
826         }
827
828         return(channel);
829 }
830
831 /*
832  * drop reserved channel and unset it.
833  * deactivation is also done
834  */
835 void PmISDN::drop_bchannel(void)
836 {
837         /* unreserve channel */
838         if (p_m_b_reserve)
839                 p_m_mISDNport->b_reserved--;
840         p_m_b_reserve = 0;
841
842         /* if not in use */
843         if (p_m_b_index < 0)
844                 return;
845         if (!p_m_b_channel)
846                 return;
847
848         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
849
850         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
851                 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
852         p_m_mISDNport->b_port[p_m_b_index] = NULL;
853         p_m_mISDNport->b_mode[p_m_b_index] = 0;
854         p_m_b_index = -1;
855         p_m_b_channel = 0;
856         p_m_b_exclusive = 0;
857 }
858
859
860 /*
861  * handler
862
863 audio transmission procedure:
864 -----------------------------
865
866 * priority
867 three sources of audio transmission:
868 - crypto-data high priority
869 - tones high priority (also high)
870 - remote-data low priority
871
872 * elapsed
873 a variable that temporarily shows the number of samples elapsed since last transmission process.
874 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
875
876 * load
877 a variable that is increased whenever data is transmitted.
878 it is decreased while time elapses. it stores the number of samples that
879 are currently loaded to dsp module.
880 since clock in dsp module is the same clock for user space process, these 
881 times have no skew.
882
883 * levels
884 there are two levels:
885 p_m_preload will give the load that have to be kept in dsp.
886 ISDN_MAXLOAD (2*p_m_preload) will give the maximum load before dropping.
887
888 * procedure for low priority data
889 see txfromup() for procedure
890 in short: remote data is ignored during high priority tones
891
892 * procedure for high priority data
893 whenever load is below p_m_preload, load is filled up to p_m_preload
894 if no more data is available, load becomes empty again.
895
896 'load' variable:
897 0                    p_m_preload           ISDN_MAXLOAD
898 +--------------------+----------------------+
899 |                    |                      |
900 +--------------------+----------------------+
901
902 on empty load or on load below p_m_preload, the load is inceased to p_m_preload:
903 0                    p_m_preload           ISDN_MAXLOAD
904 +--------------------+----------------------+
905 |TTTTTTTTTTTTTTTTTTTT|                      |
906 +--------------------+----------------------+
907
908 on empty load, remote-audio causes the load with the remote audio to be increased to p_m_preload.
909 0                    p_m_preload           ISDN_MAXLOAD
910 +--------------------+----------------------+
911 |TTTTTTTTTTTTTTTTTTTTRRRRR                  |
912 +--------------------+----------------------+
913
914  */
915 void PmISDN::update_load(void)
916 {
917         /* don't trigger load event if event already active */
918         if (p_m_loadtimer.active)
919                 return;
920
921         schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
922 }
923
924 int load_timer(struct lcr_timer *timer, void *instance, int index)
925 {
926         class PmISDN *isdnport = (class PmISDN *)instance;
927
928         isdnport->load_tx();
929
930         return 0;
931 }
932
933 void PmISDN::load_tx(void)
934 {
935         int elapsed = 0;
936         int ret;
937         struct timeval current_time;
938
939         /* get elapsed */
940         gettimeofday(&current_time, NULL);
941         if (p_m_last_tv_sec) {
942                 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
943                         + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
944         }
945         /* set clock of last process! */
946         p_m_last_tv_sec = current_time.tv_sec;
947         p_m_last_tv_msec = current_time.tv_usec/1000;
948
949         /* process only if we have samples and we are active */
950         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
951                 return;
952
953         if (elapsed) {
954                 /* update load */
955                 if (elapsed < p_m_load)
956                         p_m_load -= elapsed;
957                 else
958                         p_m_load = 0;
959
960                 /* to send data, tone must be on */
961                 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
962                  && (p_m_load < p_m_preload) /* not too much load? */
963                  && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
964                         int tosend = p_m_preload - p_m_load, length; 
965                         unsigned char buf[MISDN_HEADER_LEN+tosend];
966                         struct mISDNhead *frm = (struct mISDNhead *)buf;
967                         unsigned char *p = buf+MISDN_HEADER_LEN;
968
969                         /* copy inband signalling (e.g. used by ss5) */
970                         if (p_m_inband_send_on && tosend) {
971                                 tosend -= inband_send(p, tosend);
972                         }
973
974                         /* copy crypto loops */
975                         while (p_m_crypt_msg_loops && tosend) {
976                                 /* how much do we have to send */
977                                 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
978
979                                 /* clip tosend */
980                                 if (length > tosend)
981                                         length = tosend;
982
983                                 /* copy message (part) to buffer */
984                                 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
985
986                                 /* new position */
987                                 p_m_crypt_msg_current += length;
988                                 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
989                                         /* next loop */
990                                         p_m_crypt_msg_current = 0;
991                                         p_m_crypt_msg_loops--;
992                                         if (!p_m_crypt_msg_loops)
993                                                 update_rxoff();
994 //                                      puts("eine loop weniger");
995                                 }
996
997                                 /* new length */
998                                 tosend -= length;
999                         }
1000
1001                         /* copy tones */
1002                         if (p_tone_name[0] && tosend) {
1003                                 tosend -= read_audio(p, tosend);
1004                         }
1005
1006                         /* send data */
1007                         if (p_m_preload - p_m_load - tosend > 0) {
1008                                 frm->prim = PH_DATA_REQ;
1009                                 frm->id = 0;
1010                                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+p_m_preload-p_m_load-tosend, 0, NULL, 0);
1011                                 if (ret <= 0)
1012                                         PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_preload-p_m_load-tosend);
1013                                 p_m_load += p_m_preload - p_m_load - tosend;
1014                         }
1015                 }
1016         }
1017
1018         schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
1019 }
1020
1021 /* handle timeouts */
1022 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1023 {
1024         class PmISDN *isdnport = (class PmISDN *)instance;
1025         struct lcr_msg *message;
1026
1027         PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", isdnport->p_name, isdnport->p_m_timeout.timeout.tv_sec, isdnport->p_state);
1028         /* send timeout to endpoint */
1029         message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1030         message->param.state = isdnport->p_state;
1031         message_put(message);
1032
1033         return 0;
1034 }
1035         
1036
1037 /*
1038  * whenever we get audio data from bchannel, we process it here
1039  */
1040 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1041 {
1042         unsigned int cont = *((unsigned int *)data);
1043         struct lcr_msg *message;
1044         unsigned char *p;
1045         int l;
1046
1047         if (hh->prim == PH_CONTROL_IND) {
1048                 if (len < 4) {
1049                         PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1050                         return;
1051                 }
1052                 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1053                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1054                         add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1055                         if (!p_m_dtmf)
1056                                 add_trace("info", NULL, "DTMF is disabled");
1057                         end_trace();
1058                         if (!p_m_dtmf)
1059                                 return;
1060                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1061                         message->param.dtmf = cont & DTMF_TONE_MASK;
1062                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  DTMF digit '%c'\n", p_name, message->param.dtmf);
1063                         message_put(message);
1064                         return;
1065                 }
1066                 switch(cont) {
1067                         case DSP_BF_REJECT:
1068                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1069                         add_trace("DSP-CRYPT", NULL, "error");
1070                         end_trace();
1071                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1072                         message->param.crypt.type = CC_ERROR_IND;
1073                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  reject of blowfish.\n", p_name);
1074                         message_put(message);
1075                         break;
1076
1077                         case DSP_BF_ACCEPT:
1078                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1079                         add_trace("DSP-CRYPT", NULL, "ok");
1080                         end_trace();
1081                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1082                         message->param.crypt.type = CC_ACTBF_CONF;
1083                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  accept of blowfish.\n", p_name);
1084                         message_put(message);
1085                         break;
1086
1087                         default:
1088                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1089                         add_trace("unknown", NULL, "0x%x", cont);
1090                         end_trace();
1091                 }
1092                 return;
1093         }
1094         if (hh->prim == PH_CONTROL_IND) {
1095                 switch(hh->id) {
1096                         default:
1097                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1098                         add_trace("unknown", NULL, "0x%x", hh->id);
1099                         end_trace();
1100                 }
1101                 return;
1102         }
1103         if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1104                 if (!p_m_txdata) {
1105                         /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1106                         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1107                         return;
1108                 }
1109                 /* see below (same condition) */
1110                 if (p_state!=PORT_STATE_CONNECT
1111                          && !p_m_mISDNport->tones)
1112                         return;
1113 //              printf(".");fflush(stdout);return;
1114                 if (p_record)
1115                         record(data, len, 1); // from up
1116                 return;
1117         }
1118         if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1119                 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1120                 return;
1121         }
1122
1123         /* inband is processed */
1124         if (p_m_inband_receive_on)
1125                 inband_receive(data, len);
1126
1127         /* send to remote, if bridged */
1128         bridge_tx(data, len);
1129
1130         /* calls will not process any audio data unless
1131          * the call is connected OR tones feature is enabled.
1132          */
1133 #ifndef DEBUG_COREBRIDGE
1134         if (p_state!=PORT_STATE_CONNECT
1135          && !p_m_mISDNport->tones)
1136                 return;
1137 #endif
1138
1139 #if 0
1140         /* the bearer capability must be audio in order to send and receive
1141          * audio prior or after connect.
1142          */
1143         if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1144                 return;
1145 #endif
1146
1147         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1148         if (p_m_rxoff) {
1149                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1150                 return;
1151         }
1152
1153         /* record data */
1154         if (p_record)
1155                 record(data, len, 0); // from down
1156
1157         /* randomize and listen to crypt message if enabled */
1158         if (p_m_crypt_listen) {
1159                 /* the noisy randomizer */
1160                 p = data;
1161                 l = len;
1162                 while(l--)
1163                         mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1164
1165                 cryptman_listen_bch(data, len);
1166         }
1167 }
1168
1169
1170 /*
1171  * set echotest
1172  */
1173 void PmISDN::set_echotest(int echo)
1174 {
1175         if (p_m_echo != echo) {
1176                 p_m_echo = echo;
1177                 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1178                 if (p_m_b_channel)
1179                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1180                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1181         }
1182 }
1183
1184 /*
1185  * set tone
1186  */
1187 void PmISDN::set_tone(const char *dir, const char *tone)
1188 {
1189         int id = TONE_OFF;
1190         int dsp = DSP_NONE;
1191
1192         /* if no directory is given (by extension), we use interface.conf or options.conf */
1193         if (!dir || !dir[0]) {
1194                 if (p_m_mISDNport->ifport->tones_dir[0])
1195                         dir = p_m_mISDNport->ifport->tones_dir;
1196                 else if (options.tones_dir[0])
1197                         dir = options.tones_dir;
1198         }
1199
1200         if (!tone)
1201                 tone = "";
1202         PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1203         if (!tone[0]) {
1204                 id = TONE_OFF;
1205                 goto setdsp;
1206         }
1207
1208         /* check for dsp tones */
1209         if (!strcmp(dir, "american"))
1210                 dsp = DSP_AMERICAN;
1211         if (!strcmp(dir, "german"))
1212                 dsp = DSP_GERMAN;
1213         if (!strcmp(dir, "oldgerman"))
1214                 dsp = DSP_OLDGERMAN;
1215
1216         /* check if we NOT really have to use a dsp-tone */
1217         if (dsp == DSP_NONE) {
1218                 nodsp:
1219                 if (p_m_tone)
1220                 if (p_m_b_index > -1)
1221                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1222                         PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1223                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1224                 }
1225                 p_m_tone = 0;
1226                 Port::set_tone(dir, tone);
1227                 return;
1228         }
1229
1230         /* now we USE dsp-tone, convert name */
1231         if (!strcmp(tone, "dialtone")) {
1232                 switch(dsp) {
1233                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1234                 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1235                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1236                 }
1237         } else if (!strcmp(tone, "dialpbx")) {
1238                 switch(dsp) {
1239                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1240                 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1241                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1242                 }
1243         } else if (!strcmp(tone, "ringing")) {
1244                 switch(dsp) {
1245                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1246                 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1247                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1248                 }
1249         } else if (!strcmp(tone, "ringpbx")) {
1250                 switch(dsp) {
1251                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1252                 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1253                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1254                 }
1255         } else if (!strcmp(tone, "busy")) {
1256                 busy:
1257                 switch(dsp) {
1258                 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1259                 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1260                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1261                 }
1262         } else if (!strcmp(tone, "release")) {
1263                 hangup:
1264                 switch(dsp) {
1265                 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1266                 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1267                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1268                 }
1269         } else if (!strcmp(tone, "cause_10"))
1270                 goto hangup;
1271         else if (!strcmp(tone, "cause_11"))
1272                 goto busy;
1273         else if (!strcmp(tone, "cause_22")) {
1274                 switch(dsp) {
1275                 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1276                 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1277                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1278                 }
1279         } else if (!strncmp(tone, "cause_", 6))
1280                 id = TONE_SPECIAL_INFO;
1281         else
1282                 id = TONE_OFF;
1283
1284         /* if we have a tone that is not supported by dsp */
1285         if (id==TONE_OFF && tone[0])
1286                 goto nodsp;
1287
1288         setdsp:
1289         if (p_m_tone != id) {
1290                 /* set new tone */
1291                 p_m_tone = id;
1292                 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1293                 if (p_m_b_index > -1)
1294                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1295                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1296         }
1297         /* turn user-space tones off in cases of no tone OR dsp tone */
1298         Port::set_tone("",NULL);
1299 }
1300
1301
1302 /* MESSAGE_mISDNSIGNAL */
1303 //extern struct lcr_msg *dddebug;
1304 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1305 {
1306         int oldconf, newconf;
1307         switch(param->mISDNsignal.message) {
1308                 case mISDNSIGNAL_VOLUME:
1309                 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1310                         p_m_tx_gain = param->mISDNsignal.tx_gain;
1311                         PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1312                         if (p_m_b_index > -1)
1313                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1314                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1315                 } else
1316                         PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1317                 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1318                         p_m_rx_gain = param->mISDNsignal.rx_gain;
1319                         PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1320                         if (p_m_b_index > -1)
1321                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1322                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1323                 } else
1324                         PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1325                 break;
1326
1327                 case mISDNSIGNAL_CONF:
1328                 oldconf = p_m_mute?0:p_m_conf;
1329                 p_m_conf = param->mISDNsignal.conf;
1330                 newconf = p_m_mute?0:p_m_conf;
1331                 set_conf(oldconf, newconf);
1332                 break;
1333
1334                 case mISDNSIGNAL_DELAY:
1335                 if (p_m_delay != param->mISDNsignal.delay) {
1336                         p_m_delay = param->mISDNsignal.delay;
1337                         PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1338                         if (p_m_b_index > -1)
1339                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1340                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1341                 } else
1342                         PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1343                 break;
1344
1345                 default:
1346                 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1347         }
1348 }
1349
1350 /* MESSAGE_CRYPT */
1351 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1352 {
1353         struct lcr_msg *message;
1354
1355         switch(param->crypt.type) {
1356                 case CC_ACTBF_REQ:           /* activate blowfish */
1357                 p_m_crypt = 1;
1358                 p_m_crypt_key_len = param->crypt.len;
1359                 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1360                         PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1361                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1362                         message->param.crypt.type = CC_ERROR_IND;
1363                         message_put(message);
1364                         break;
1365                 }
1366                 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1367                 crypt_off:
1368                 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1369                 if (p_m_b_index > -1)
1370                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1371                         ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1372                 break;
1373
1374                 case CC_DACT_REQ:            /* deactivate session encryption */
1375                 p_m_crypt = 0;
1376                 goto crypt_off;
1377                 break;
1378
1379                 case CR_LISTEN_REQ:          /* start listening to messages */
1380                 p_m_crypt_listen = 1;
1381                 update_rxoff();
1382                 p_m_crypt_listen_state = 0;
1383                 break;
1384
1385                 case CR_UNLISTEN_REQ:        /* stop listening to messages */
1386                 p_m_crypt_listen = 0;
1387                 update_rxoff();
1388                 break;
1389
1390                 case CR_MESSAGE_REQ:         /* send message */
1391                 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1392                 if (!p_m_crypt_msg_len) {
1393                         PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1394                         break;
1395                 }
1396                 p_m_crypt_msg_current = 0; /* reset */
1397                 p_m_crypt_msg_loops = 6; /* enable */
1398                 update_rxoff();
1399 #if 0
1400                 /* disable txmix, or we get corrupt data due to audio process */
1401                 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1402                         PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1403                         ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1404                 }
1405 #endif
1406                 break;
1407
1408                 default:
1409                 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1410         }
1411
1412 }
1413
1414 /*
1415  * endpoint sends messages to the port
1416  */
1417 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1418 {
1419         if (Port::message_epoint(epoint_id, message_id, param)) {
1420                 if (message_id == MESSAGE_BRIDGE)
1421                         update_rxoff();
1422                 return 1;
1423         }
1424
1425         switch(message_id) {
1426                 case MESSAGE_mISDNSIGNAL: /* user command */
1427                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1428                 message_mISDNsignal(epoint_id, message_id, param);
1429                 return 1;
1430
1431                 case MESSAGE_CRYPT: /* crypt control command */
1432                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1433                 message_crypt(epoint_id, message_id, param);
1434                 return 1;
1435
1436                 case MESSAGE_DISABLE_DEJITTER:
1437                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received de-jitter disable order.\n", p_name);
1438                 p_m_disable_dejitter = 1;
1439                 p_m_preload = param->queue;
1440                 update_rxoff();
1441                 return 1;
1442         }
1443
1444         return 0;
1445 }
1446
1447 void PmISDN::update_rxoff(void)
1448 {
1449         int tx_dejitter = 0;
1450
1451         /* call bridges in user space OR crypto OR recording */
1452         if (p_bridge || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1453                 /* rx IS required */
1454                 if (p_m_rxoff) {
1455                         /* turn on RX */
1456                         p_m_rxoff = 0;
1457                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1458                         if (p_m_b_index > -1)
1459                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1460                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1461                 }
1462         } else {
1463                 /* rx NOT required */
1464                 if (!p_m_rxoff) {
1465                         /* turn off RX */
1466                         p_m_rxoff = 1;
1467                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1468                         if (p_m_b_index > -1)
1469                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1470                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1471                 }
1472         }
1473         /* recording */
1474         if (p_record) {
1475                 /* txdata IS required */
1476                 if (!p_m_txdata) {
1477                         /* turn on RX */
1478                         p_m_txdata = 1;
1479                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1480                         if (p_m_b_index > -1)
1481                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1482                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1483                 }
1484         } else {
1485                 /* txdata NOT required */
1486                 if (p_m_txdata) {
1487                         /* turn off RX */
1488                         p_m_txdata = 0;
1489                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1490                         if (p_m_b_index > -1)
1491                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1492                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1493                 }
1494         }
1495         /* dejitter on bridge */
1496         if (p_bridge && !p_m_disable_dejitter)
1497                 tx_dejitter = 1;
1498         if (p_m_tx_dejitter != tx_dejitter) {
1499                 p_m_tx_dejitter = tx_dejitter;
1500                 PDEBUG(DEBUG_BCHANNEL, "we change dejitter mode to %s.\n", (p_m_tx_dejitter) ? "on" : "off");
1501                 if (p_m_b_index > -1)
1502                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1503                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TX_DEJITTER, p_m_tx_dejitter, "DSP-TX_DEJITTER", p_m_tx_dejitter);
1504         }
1505 }
1506
1507 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1508 {
1509         struct mISDNport *mISDNport;
1510         struct mbuffer *mb;
1511         struct l3_msg *l3m;
1512         char byte;
1513         int ret;
1514
1515         /* unset global semaphore */
1516         upqueue_avail = 0;
1517         // with a very small incident, upqueue_avail may be set by mISDN thread and
1518         // another byte may be sent to the pipe, which causes a call to this function
1519         // again with nothing in the upqueue. this is no problem.
1520         ret = read(fd->fd, &byte, 1);
1521
1522         /* process all ports */
1523         mISDNport = mISDNport_first;
1524         while(mISDNport) {
1525                 /* handle queued up-messages (d-channel) */
1526                 while ((mb = mdequeue(&mISDNport->upqueue))) {
1527                         l3m = &mb->l3;
1528                         switch(l3m->type) {
1529                                 case MPH_ACTIVATE_IND:
1530                                 if (mISDNport->l1link != 1) {
1531                                         l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1532                                         end_trace();
1533                                         mISDNport->l1link = 1;
1534                                 }
1535                                 break;
1536         
1537                                 case MPH_DEACTIVATE_IND:
1538                                 if (mISDNport->l1link != 0) {
1539                                         l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1540                                         end_trace();
1541                                         mISDNport->l1link = 0;
1542                                 }
1543                                 break;
1544
1545                                 case MPH_INFORMATION_IND:
1546                                 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1547                                 switch (l3m->pid) {
1548                                         case L1_SIGNAL_LOS_ON:
1549                                         mISDNport->los = 1;
1550                                         break;
1551                                         case L1_SIGNAL_LOS_OFF:
1552                                         mISDNport->los = 0;
1553                                         break;
1554                                         case L1_SIGNAL_AIS_ON:
1555                                         mISDNport->ais = 1;
1556                                         break;
1557                                         case L1_SIGNAL_AIS_OFF:
1558                                         mISDNport->ais = 0;
1559                                         break;
1560                                         case L1_SIGNAL_RDI_ON:
1561                                         mISDNport->rdi = 1;
1562                                         break;
1563                                         case L1_SIGNAL_RDI_OFF:
1564                                         mISDNport->rdi = 0;
1565                                         break;
1566                                         case L1_SIGNAL_SLIP_TX:
1567                                         mISDNport->slip_tx++;
1568                                         break;
1569                                         case L1_SIGNAL_SLIP_RX:
1570                                         mISDNport->slip_rx++;
1571                                         break;
1572                                 }
1573                                 break;
1574
1575                                 case MT_L2ESTABLISH:
1576                                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1577                                 add_trace("tei", NULL, "%d", l3m->pid);
1578                                 end_trace();
1579                                 mISDNport->l2link = 1;
1580                                 if (l3m->pid < 128)
1581                                         mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1582                                 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1583                                         if (mISDNport->l2establish.active) {
1584                                                 unsched_timer(&mISDNport->l2establish);
1585                                                 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1586                                         }
1587                                 }
1588                                 break;
1589
1590                                 case MT_L2RELEASE:
1591                                 if (l3m->pid < 128)
1592                                         mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1593                                 if (!mISDNport->l2establish.active) {
1594                                         l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1595                                         add_trace("tei", NULL, "%d", l3m->pid);
1596                                         end_trace();
1597                                         /* down if not nt-ptmp */ 
1598                                         if (!mISDNport->ntmode || mISDNport->ptp)
1599                                                 mISDNport->l2link = 0;
1600                                 }
1601                                 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1602                                         if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1603                                                 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1604                                                 schedule_timer(&mISDNport->l2establish, 5, 0);
1605                                                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1606                                         }
1607                                 }
1608                                 break;
1609
1610                                 default:
1611                                 /* l3-data is sent to LCR */
1612                                 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1613                         }
1614                         /* free message */
1615                         free_l3_msg(l3m);
1616                 }
1617                 mISDNport = mISDNport->next;
1618         }
1619         return 0;
1620 }
1621
1622 /* l2 establish timer fires */
1623 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1624 {
1625         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1626
1627         if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1628                 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1629                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1630                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1631         }
1632
1633         return 0;
1634 }
1635
1636 /* handle frames from bchannel */
1637 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1638 {
1639         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1640         unsigned char buffer[2048+MISDN_HEADER_LEN];
1641         struct mISDNhead *hh = (struct mISDNhead *)buffer;
1642         int ret;
1643
1644         ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1645         if (ret < 0) {
1646                 PERROR("read error frame, errno %d\n", errno);
1647                 return 0;
1648         }
1649         if (ret < (int)MISDN_HEADER_LEN) {
1650                 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1651                 return 0;
1652         }
1653         switch(hh->prim) {
1654                 /* we don't care about confirms, we use rx data to sync tx */
1655                 case PH_DATA_CNF:
1656                 break;
1657
1658                 /* we receive audio data, we respond to it AND we send tones */
1659                 case PH_DATA_IND:
1660                 case DL_DATA_IND:
1661                 case PH_DATA_REQ:
1662                 case DL_DATA_REQ:
1663                 case PH_CONTROL_IND:
1664                 if (mISDNport->b_port[i])
1665                         mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1666                 else
1667                         PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1668                 break;
1669
1670                 case PH_ACTIVATE_IND:
1671                 case DL_ESTABLISH_IND:
1672                 case PH_ACTIVATE_CNF:
1673                 case DL_ESTABLISH_CNF:
1674                 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1675                 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1676                 break;
1677
1678                 case PH_DEACTIVATE_IND:
1679                 case DL_RELEASE_IND:
1680                 case PH_DEACTIVATE_CNF:
1681                 case DL_RELEASE_CNF:
1682                 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
1683                 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1684                 break;
1685
1686                 default:
1687                 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
1688         }
1689
1690         return 0;
1691 }
1692
1693 /* process timer events for bchannel handling */
1694 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
1695 {
1696         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1697
1698         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1699
1700         return 0;
1701 }
1702
1703
1704 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1705 {
1706         /* IMPORTAINT:
1707          *
1708          * l3m must be queued, except for MT_ASSIGN
1709          *
1710          */
1711         struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
1712         struct mbuffer *mb;
1713
1714 #ifdef OLD_MT_ASSIGN
1715         /* special MT_ASSIGN handling:
1716          *
1717          * if we request a PID from mlayer, we always do it while lcr is locked.
1718          * therefore we must check the MT_ASSIGN reply first before we lock.
1719          * this is because the MT_ASSIGN reply is received with the requesting
1720          * process, not by the mlayer thread!
1721          * this means, that the reply is sent during call of the request.
1722          * we must check if we get a reply and we know that we lcr is currently
1723          * locked.
1724          */
1725         if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
1726                 /* let's do some checking if someone changes stack behaviour */
1727                 if (mt_assign_pid != 0)
1728                         FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
1729                 mt_assign_pid = pid;
1730                 return(0);
1731         }
1732 #endif
1733         /* queue message, create, if required */
1734         if (!l3m) {
1735                 l3m = alloc_l3_msg();
1736                 if (!l3m)
1737                         FATAL("No memory for layer 3 message\n");
1738         }
1739         mb = container_of(l3m, struct mbuffer, l3);
1740         l3m->type = cmd;
1741         l3m->pid = pid;
1742         mqueue_tail(&mISDNport->upqueue, mb);
1743         if (!upqueue_avail) {
1744                 // multiple threads may cause multiple calls of this section, but this
1745                 // results only in multiple processing of the upqueue read.
1746                 // this is no problem.
1747                 upqueue_avail = 1;
1748                 char byte = 0;
1749                 int ret;
1750                 ret = write(upqueue_pipe[1], &byte, 1);
1751         }
1752         return 0;
1753 }
1754
1755 int mISDN_getportbyname(int sock, int cnt, char *portname)
1756 {
1757         struct mISDN_devinfo devinfo;
1758         int port = 0, ret;
1759
1760         /* resolve name */
1761         while (port < cnt) {
1762                 devinfo.id = port;
1763                 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
1764                 if (ret < 0)
1765                         return ret;
1766                 if (!strcasecmp(devinfo.name, portname))
1767                         break;
1768                 port++;
1769         }
1770         if (port == cnt)
1771                 return -EIO;
1772
1773         return (port);
1774 }
1775
1776 /*
1777  * global function to add a new card (port)
1778  */
1779 struct mISDNport *mISDNport_open(struct interface_port *ifport)
1780 {
1781         int ret;
1782         struct mISDNport *mISDNport, **mISDNportp;
1783         int port = ifport->portnum;
1784         int ptp = ifport->ptp;
1785         int force_nt = ifport->nt;
1786         int l1hold = ifport->l1hold;
1787         int l2hold = ifport->l2hold;
1788         int ss5 = ifport->ss5;
1789         int i, cnt;
1790         int pri, bri, pots;
1791         int nt, te;
1792 //      struct mlayer3 *ml3;
1793         struct mISDN_devinfo devinfo;
1794         unsigned int protocol, prop;
1795
1796         /* check port counts */
1797         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
1798         if (ret < 0) {
1799                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
1800                 return(NULL);
1801         }
1802
1803         if (cnt <= 0) {
1804                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
1805                 return(NULL);
1806         }
1807         if (port < 0) {
1808                 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
1809                 if (port < 0) {
1810                         PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
1811                         return(NULL);
1812                 }
1813                 // note: 'port' has still the port number
1814         }
1815         if (port>cnt || port<0) {
1816                 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
1817                 return(NULL);
1818         }
1819
1820         /* get port attributes */
1821         pri = bri = pots = nt = te = 0;
1822         devinfo.id = port;
1823         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
1824         if (ret < 0) {
1825                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
1826                 return(NULL);
1827         }
1828         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
1829                 bri = 1;
1830                 te = 1;
1831         }
1832         if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
1833                 bri = 1;
1834                 nt = 1;
1835         }
1836         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
1837                 pri = 1;
1838                 te = 1;
1839         }
1840         if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
1841                 pri = 1;
1842                 nt = 1;
1843         }
1844 #ifdef ISDN_P_FXS
1845         if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
1846                 pots = 1;
1847                 te = 1;
1848         }
1849 #endif
1850 #ifdef ISDN_P_FXO
1851         if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
1852                 pots = 1;
1853                 nt = 1;
1854         }
1855 #endif
1856         if (force_nt && !nt) {
1857                 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
1858                 return(NULL);
1859         }
1860         if (bri && pri) {
1861                 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
1862                 return(NULL);
1863         }
1864         if (pots && !bri && !pri) {
1865                 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
1866                 return(NULL);
1867         }
1868         if (!bri && !pri) {
1869                 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
1870                 return(NULL);
1871         }
1872         if (!nt && !te) {
1873                 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
1874                 return(NULL);
1875         }
1876         /* set NT by turning off TE */
1877         if (force_nt && nt)
1878                 te = 0;
1879         /* if TE an NT is supported (and not forced to NT), turn off NT */
1880         if (te && nt)
1881                 nt = 0;
1882
1883         /* check for double use of port */
1884         if (nt) {
1885                 mISDNport = mISDNport_first;
1886                 while(mISDNport) {
1887                         if (mISDNport->portnum == port)
1888                                 break;
1889                         mISDNport = mISDNport->next;
1890                 }
1891                 if (mISDNport) {
1892                         PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
1893                         return(NULL);
1894                 }
1895         }
1896
1897         /* check for continous channelmap with no bchannel on slot 16 */
1898         if (test_channelmap(0, devinfo.channelmap)) {
1899                 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
1900                 return(NULL);
1901         }
1902         i = 1;
1903         while(i < (int)devinfo.nrbchan + 1) {
1904                 if (i == 16) {
1905                         if (test_channelmap(i, devinfo.channelmap)) {
1906                                 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
1907                                 return(NULL);
1908                         }
1909                 } else {
1910                         if (!test_channelmap(i, devinfo.channelmap)) {
1911                                 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
1912                                 return(NULL);
1913                         }
1914                 }
1915                 i++;
1916         }
1917
1918         /* add mISDNport structure */
1919         mISDNportp = &mISDNport_first;
1920         while(*mISDNportp)
1921                 mISDNportp = &((*mISDNportp)->next);
1922         mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
1923         add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
1924         if (ss5) {
1925                 /* ss5 link is always active */
1926                 mISDNport->l1link = 1;
1927                 mISDNport->l2link = 1;
1928         } else {
1929                 mISDNport->l1link = -1;
1930                 mISDNport->l2link = -1;
1931         }
1932         pmemuse++;
1933         *mISDNportp = mISDNport;
1934
1935         /* if pri, must set PTP */
1936         if (pri)
1937                 ptp = 1;
1938
1939         /* set ss5 params */
1940         if (ss5) {
1941                 /* try to keep interface enabled */
1942                 l1hold = 1;
1943                 l2hold = 0;
1944         }
1945         /* set l2hold */
1946         switch (l2hold) {
1947                 case -1: // off
1948                 l2hold = 0;
1949                 break;
1950                 case 1: // on
1951                 l2hold = 1;
1952                 break;
1953                 default:
1954                 if (ptp)
1955                         l2hold = 1;
1956                 else
1957                         l2hold = 0;
1958                 break;
1959         }
1960                 
1961         /* allocate ressources of port */
1962         protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
1963         prop = (1 << MISDN_FLG_L2_CLEAN);
1964         if (ptp) // ptp forced
1965                prop |= (1 << MISDN_FLG_PTP);
1966         if (nt) // supports hold/retrieve on nt-mode
1967                prop |= (1 << MISDN_FLG_NET_HOLD);
1968         if (l1hold) // supports layer 1 hold
1969                prop |= (1 << MISDN_FLG_L1_HOLD);
1970         if (l2hold) // supports layer 2 hold
1971                prop |= (1 << MISDN_FLG_L2_HOLD);
1972         /* open layer 3 and init upqueue */
1973         /* queue must be initializes, because l3-thread may send messages during open_layer3() */
1974         mqueue_init(&mISDNport->upqueue);
1975         mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
1976         if (!mISDNport->ml3) {
1977                 mqueue_purge(&mISDNport->upqueue);
1978                 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
1979                 start_trace(port,
1980                         ifport->interface,
1981                         NULL,
1982                         NULL,
1983                         DIRECTION_NONE,
1984                         CATEGORY_CH,
1985                         0,
1986                         "PORT (open failed)");
1987                 end_trace();
1988                 mISDNport_close(mISDNport);
1989                 return(NULL);
1990         }
1991
1992         SCPY(mISDNport->name, devinfo.name);
1993         mISDNport->b_num = devinfo.nrbchan;
1994         mISDNport->portnum = port;
1995         mISDNport->ntmode = nt;
1996         mISDNport->tespecial = ifport->tespecial;
1997         mISDNport->pri = pri;
1998         mISDNport->ptp = ptp;
1999         mISDNport->l1hold = l1hold;
2000         mISDNport->l2hold = l2hold;
2001         mISDNport->ss5 = ss5;
2002         PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2003         i = 0;
2004         while(i < mISDNport->b_num) {
2005                 mISDNport->b_state[i] = B_STATE_IDLE;
2006                 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2007                 i++;
2008         }
2009
2010         /* if ptp, pull up the link */
2011         if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2012                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2013                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2014                 add_trace("tei", NULL, "%d", 0);
2015                 end_trace();
2016                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2017         }
2018
2019         /* for nt-mode ptmp the link is always up */
2020         if (mISDNport->ntmode && !mISDNport->ptp)
2021                 mISDNport->l2link = 1;
2022
2023         PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2024
2025         start_trace(mISDNport->portnum,
2026                     ifport->interface,
2027                     NULL,
2028                     NULL,
2029                     DIRECTION_NONE,
2030                     CATEGORY_CH,
2031                     0,
2032                     "PORT (open)");
2033         add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2034         add_trace("channels", NULL, "%d", mISDNport->b_num);
2035         if (mISDNport->ss5)
2036                 add_trace("ccitt#5", NULL, "enabled");
2037         end_trace();
2038
2039         return(mISDNport);
2040 }
2041
2042
2043 /*
2044  * load static port instances, if required by mISDNport
2045  */
2046 void mISDNport_static(struct mISDNport *mISDNport)
2047 {
2048         int i;
2049
2050         i = 0;
2051         while(i < mISDNport->b_num) {
2052 #ifdef WITH_SS5
2053                 if (mISDNport->ss5)
2054                         ss5_create_channel(mISDNport, i);
2055 #endif
2056                 i++;
2057         }
2058 }
2059
2060
2061 /*
2062  * function to free ALL cards (ports)
2063  */
2064 void mISDNport_close_all(void)
2065 {
2066         /* free all ports */
2067         while(mISDNport_first)
2068                 mISDNport_close(mISDNport_first);
2069 }
2070
2071 /*
2072  * free only one port
2073  */
2074 void mISDNport_close(struct mISDNport *mISDNport)
2075 {
2076         struct mISDNport **mISDNportp;
2077         class Port *port;
2078         class PmISDN *isdnport;
2079         int i;
2080
2081         /* remove all port instance that are linked to this mISDNport */
2082         again:
2083         port = port_first;
2084         while(port) {
2085                 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2086                         isdnport = (class PmISDN *)port;
2087                         if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2088                                 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2089                                 delete isdnport;
2090                                 goto again;
2091                         }
2092                 }
2093                 port = port->next;
2094         }
2095
2096         /* only if we are already part of interface */
2097         if (mISDNport->ifport) {
2098                 start_trace(mISDNport->portnum,
2099                             mISDNport->ifport->interface,
2100                             NULL,
2101                             NULL,
2102                             DIRECTION_NONE,
2103                             CATEGORY_CH,
2104                             0,
2105                             "PORT (close)");
2106                 end_trace();
2107         }
2108
2109         /* free bchannels */
2110         i = 0;
2111         while(i < mISDNport->b_num) {
2112                 if (mISDNport->b_sock[i].inuse) {
2113                         _bchannel_destroy(mISDNport, i);
2114                         PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2115                 }
2116                 if (mISDNport->b_timer[i].inuse) {
2117                         del_timer(&mISDNport->b_timer[i]);
2118                 }
2119                 i++;
2120         }
2121         del_timer(&mISDNport->l2establish);
2122
2123         /* close layer 3, if open */
2124         if (mISDNport->ml3) {
2125                 close_layer3(mISDNport->ml3);
2126         }
2127
2128         /* purge upqueue */
2129         mqueue_purge(&mISDNport->upqueue);
2130
2131         /* remove from list */
2132         mISDNportp = &mISDNport_first;
2133         while(*mISDNportp) {
2134                 if (*mISDNportp == mISDNport) {
2135                         *mISDNportp = (*mISDNportp)->next;
2136                         mISDNportp = NULL;
2137                         break;
2138                 }
2139                 mISDNportp = &((*mISDNportp)->next);
2140         }
2141
2142         if (mISDNportp)
2143                 FATAL("mISDNport not in list\n");
2144         
2145         FREE(mISDNport, sizeof(struct mISDNport));
2146         pmemuse--;
2147
2148 }
2149
2150
2151 /*
2152  * enque data from remote port
2153  */
2154 int PmISDN::bridge_rx(unsigned char *data, int length)
2155 {
2156         unsigned char buf[MISDN_HEADER_LEN+((length>p_m_preload)?length:p_m_preload)];
2157         struct mISDNhead *hh = (struct mISDNhead *)buf;
2158         int ret;
2159
2160         if (p_m_b_index < 0)
2161                 return -EIO;
2162         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2163                 return -EINVAL;
2164
2165         /* check if high priority tones exist
2166          * ignore data in this case
2167          */
2168         if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2169                 return -EBUSY;
2170
2171         /* preload procedure
2172          * if transmit buffer in DSP module is empty,
2173          * preload it to DSP_LOAD to prevent jitter gaps.
2174          * 
2175          * if load runs empty, preload again.
2176          */
2177         if (p_m_disable_dejitter && p_m_load == 0 && p_m_preload > 0) {
2178 //printf("preload=%d\n", p_m_preload);
2179                 hh->prim = PH_DATA_REQ; 
2180                 hh->id = 0;
2181                 memset(buf+MISDN_HEADER_LEN, silence, p_m_preload);
2182                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+p_m_preload, 0, NULL, 0);
2183                 if (ret <= 0)
2184                         PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2185                 p_m_load += p_m_preload;
2186                 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
2187         }
2188
2189         /* drop if load would exceed ISDN_MAXLOAD
2190          * this keeps the delay not too high
2191          */
2192 //printf("load=%d len=%d 2*preload=%d\n", p_m_load, length, p_m_preload << 1);
2193         if (p_m_disable_dejitter && p_m_preload > 0 && p_m_load+length > (p_m_preload << 1))
2194                 return -EINVAL;
2195
2196         /* make and send frame */
2197         hh->prim = PH_DATA_REQ;
2198         hh->id = 0;
2199         memcpy(buf+MISDN_HEADER_LEN, data, length);
2200         ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2201         if (ret <= 0)
2202                 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2203         p_m_load += length;
2204
2205         return 0;
2206 }
2207
2208 int PmISDN::inband_send(unsigned char *buffer, int len)
2209 {
2210         PERROR("this function must be derived to function!\n");
2211         return 0;
2212 }
2213
2214 void PmISDN::inband_send_on(void)
2215 {
2216         PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2217         p_m_inband_send_on = 1;
2218 }
2219
2220 void PmISDN::inband_send_off(void)
2221 {
2222         PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2223         p_m_inband_send_on = 0;
2224 }
2225
2226 void PmISDN::inband_receive(unsigned char *buffer, int len)
2227 {
2228 //
2229 //      if (len >= SS5_DECODER_NPOINTS)
2230 //              ss5_decode(buffer, SS5_DECODER_NPOINTS);
2231         PERROR("this function must be derived to function!\n");
2232 }
2233
2234 void PmISDN::inband_receive_on(void)
2235 {
2236         /* this must work during constructor, see ss5.cpp */
2237         PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2238         p_m_inband_receive_on = 1;
2239         update_rxoff();
2240 }
2241
2242 void PmISDN::inband_receive_off(void)
2243 {
2244         PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2245         p_m_inband_receive_on = 0;
2246         update_rxoff();
2247 }
2248
2249 void PmISDN::mute_on(void)
2250 {
2251         if (p_m_mute)
2252                 return;
2253         PDEBUG(DEBUG_PORT, "turning mute on.\n");
2254         p_m_mute = 1;
2255         set_conf(p_m_conf, 0);
2256 }
2257
2258 void PmISDN::mute_off(void)
2259 {
2260         if (!p_m_mute)
2261                 return;
2262         PDEBUG(DEBUG_PORT, "turning mute off.\n");
2263         p_m_mute = 0;
2264         set_conf(0, p_m_conf);
2265 }
2266
2267