gsm: Implement the size checking of the hello packet
[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, int channel, int exclusive, int mode) : Port(type, portname, settings)
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_echo = 0;
143         p_m_tone = 0;
144         p_m_rxoff = 0;
145         p_m_inband_send_on = 0;
146         p_m_inband_receive_on = 0;
147         p_m_dtmf = !mISDNport->ifport->nodtmf;
148         memset(&p_m_timeout, 0, sizeof(p_m_timeout));
149         add_timer(&p_m_timeout, mISDN_timeout, this, 0);
150         p_m_remote_ref = 0; /* channel shall be exported to given remote */
151         p_m_remote_id = 0; /* remote admin socket */
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 Also the bchannel may be exported, but only if the state is or becomes idle:
572
573 - B_STATE_EXPORTING
574 The bchannel assignment has been sent to the remove application.
575
576 - B_STATE_REMOTE
577 The bchannel assignment is acknowledged by the remote application.
578
579 - B_STATE_IMPORTING
580 The bchannel is re-imported by mISDN port object.
581
582 - B_STATE_IDLE
583 See above.
584 After re-importing bchannel, and if not used, the bchannel becomes idle again.
585
586
587 A bchannel can have the following events:
588
589 - B_EVENT_USE
590 A bchannel is required by a Port class.
591
592 - B_EVENT_ACTIVATED
593 The bchannel beomes active.
594
595 - B_EVENT_DROP
596 The bchannel is not required by Port class anymore
597
598 - B_EVENT_DEACTIVATED
599 The bchannel becomes inactive.
600
601 - B_EVENT_EXPORTED
602 The bchannel is now used by remote application.
603
604 - B_EVENT_IMPORTED
605 The bchannel is not used by remote application.
606
607 - B_EVENT_EXPORTREQUEST
608 The bchannel shall be exported to the remote application.
609
610 - B_EVENT_IMPORTREQUEST
611 The bchannel is released from the remote application.
612
613 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
614
615 if an export request is receive by remote application, p_m_remote_* is set.
616 the b_remote_*[index] indicates if and where the channel is exported to. (set from the point on, where export is initiated, until imported is acknowledged.)
617 - set on export request from remote application (if port is assigned)
618 - set on channel use, if requested by remote application (p_m_remote_*)
619 - cleared on drop request
620
621 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
622 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
623 the bchannel import/export is acknowledged with stack given.
624
625 if exporting, b_remote_*[index] is set to the remote socket id.
626 if importing has been acknowledged. b_remote_*[index] is cleared.
627
628 */
629
630 /*
631  * process bchannel events
632  * - mISDNport is a pointer to the port's structure
633  * - i is the index of the bchannel
634  * - event is the B_EVENT_* value
635  * - port is the PmISDN class pointer
636  */
637 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
638 {
639         class PmISDN *b_port = mISDNport->b_port[i];
640         int state = mISDNport->b_state[i];
641         int timer = -1; // no change
642         unsigned int p_m_remote_ref = 0;
643         unsigned int p_m_remote_id = 0;
644         int p_m_tx_gain = 0;
645         int p_m_rx_gain = 0;
646         char *p_m_pipeline = NULL;
647         unsigned char *p_m_crypt_key = NULL;
648         int p_m_crypt_key_len = 0;
649         int p_m_crypt_key_type = 0;
650         unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
651
652         if (b_port) {
653                 p_m_remote_id = b_port->p_m_remote_id;
654                 p_m_remote_ref = b_port->p_m_remote_ref;
655                 p_m_tx_gain = b_port->p_m_tx_gain;
656                 p_m_rx_gain = b_port->p_m_rx_gain;
657                 p_m_pipeline = b_port->p_m_pipeline;
658                 p_m_crypt_key = b_port->p_m_crypt_key;
659                 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
660                 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
661         }
662
663         switch(event) {
664                 case B_EVENT_USE:
665                 /* port must be linked in order to allow activation */
666                 if (!b_port)
667                         FATAL("bchannel must be linked to a Port class\n");
668                 switch(state) {
669                         case B_STATE_IDLE:
670                         if (p_m_remote_ref) {
671                                 /* export bchannel */
672                                 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
673                                 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
674                                 add_trace("type", NULL, "assign");
675                                 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
676                                 end_trace();
677                                 state = B_STATE_EXPORTING;
678                                 mISDNport->b_remote_id[i] = p_m_remote_id;
679                                 mISDNport->b_remote_ref[i] = p_m_remote_ref;
680                         } else {
681                                 /* create stack and send activation request */
682                                 if (_bchannel_create(mISDNport, i)) {
683                                         _bchannel_activate(mISDNport, i, 1, 0);
684                                         state = B_STATE_ACTIVATING;
685                                         timer = B_TIMER_ACTIVATING;
686                                 }
687                         }
688                         break;
689
690                         case B_STATE_ACTIVATING:
691                         case B_STATE_EXPORTING:
692                         /* do nothing, because it is already activating */
693                         break;
694
695                         case B_STATE_DEACTIVATING:
696                         case B_STATE_IMPORTING:
697                         /* do nothing, because we must wait until we can reactivate */
698                         break;
699
700                         default:
701                         /* problems that might ocurr:
702                          * B_EVENT_USE is received when channel already in use.
703                          * bchannel exported, but not freed by other port
704                          */
705                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
706                 }
707                 break;
708
709                 case B_EVENT_EXPORTREQUEST:
710                 /* special case where the bchannel is requested by remote */
711                 if (!p_m_remote_ref) {
712                         PERROR("export request without remote channel set, please correct.\n");
713                         break;
714                 }
715                 switch(state) {
716                         case B_STATE_IDLE:
717                         /* in case, the bchannel is exported right after seize_bchannel */
718                         /* export bchannel */
719                         /* p_m_remote_id is set, when this event happens. */
720                         message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
721                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
722                         add_trace("type", NULL, "assign");
723                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
724                         end_trace();
725                         state = B_STATE_EXPORTING;
726                         mISDNport->b_remote_id[i] = p_m_remote_id;
727                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
728                         break;
729
730                         case B_STATE_ACTIVATING:
731                         case B_STATE_EXPORTING:
732                         /* do nothing, because it is already activating */
733                         break;
734
735                         case B_STATE_DEACTIVATING:
736                         case B_STATE_IMPORTING:
737                         /* do nothing, because we must wait until we can reactivate */
738                         break;
739
740                         case B_STATE_ACTIVE:
741                         /* bchannel is active, so we deactivate */
742                         _bchannel_activate(mISDNport, i, 0, 0);
743                         state = B_STATE_DEACTIVATING;
744                         timer = B_TIMER_DEACTIVATING;
745                         break;
746
747                         default:
748                         /* problems that might ocurr:
749                          * ... when channel already in use.
750                          * bchannel exported, but not freed by other port
751                          */
752                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
753                 }
754                 break;
755
756                 case B_EVENT_IMPORTREQUEST:
757                 /* special case where the bchannel is released by remote */
758                 if (p_m_remote_ref) {
759                         PERROR("import request with remote channel set, please correct.\n");
760                         break;
761                 }
762                 switch(state) {
763                         case B_STATE_IDLE:
764                         case B_STATE_ACTIVE:
765                         /* bchannel is not exported */
766                         break;
767
768                         case B_STATE_ACTIVATING:
769                         case B_STATE_EXPORTING:
770                         /* do nothing because we must wait until bchanenl is active before deactivating */
771                         break;
772
773                         case B_STATE_REMOTE:
774                         /* bchannel is exported, so we re-import */
775                         message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
776                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
777                         add_trace("type", NULL, "remove");
778                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
779                         end_trace();
780                         state = B_STATE_IMPORTING;
781                         break;
782
783                         case B_STATE_DEACTIVATING:
784                         case B_STATE_IMPORTING:
785                         /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
786                         break;
787
788                         default:
789                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
790                 }
791                 break;
792
793                 case B_EVENT_ACTIVATED:
794                 timer = 0;
795                 switch(state) {
796                         case B_STATE_ACTIVATING:
797                         if (b_port && !p_m_remote_id) {
798                                 /* bchannel is active and used by Port class, so we configure bchannel */
799                                 _bchannel_configure(mISDNport, i);
800                                 state = B_STATE_ACTIVE;
801                                 b_port->p_m_load = 0;
802                         } else {
803                                 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
804                                 _bchannel_activate(mISDNport, i, 0, 0);
805                                 state = B_STATE_DEACTIVATING;
806                                 timer = B_TIMER_DEACTIVATING;
807                         }
808                         break;
809
810                         default:
811                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
812                 }
813                 break;
814
815                 case B_EVENT_EXPORTED:
816                 switch(state) {
817                         case B_STATE_EXPORTING:
818                         if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
819                                 /* remote export done */
820                                 state = B_STATE_REMOTE;
821                         } else {
822                                 /* bchannel is now exported, but we need bchannel back
823                                  * OR bchannel is not used anymore
824                                  * OR bchannel has been exported to an obsolete ref,
825                                  * so reimport, to later export to new remote */
826                                 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
827                                 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
828                                 add_trace("type", NULL, "remove");
829                                 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
830                                 end_trace();
831                                 state = B_STATE_IMPORTING;
832                         }
833                         break;
834
835                         default:
836                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
837                 }
838                 break;
839
840                 case B_EVENT_DROP:
841                 if (!b_port)
842                         FATAL("bchannel must be linked to a Port class\n");
843                 switch(state) {
844                         case B_STATE_IDLE:
845                         /* bchannel is idle due to an error, so we do nothing */
846                         break;
847
848                         case B_STATE_ACTIVATING:
849                         case B_STATE_EXPORTING:
850                         /* do nothing because we must wait until bchanenl is active before deactivating */
851                         break;
852
853                         case B_STATE_ACTIVE:
854                         /* bchannel is active, so we deactivate */
855                         _bchannel_activate(mISDNport, i, 0, 0);
856                         state = B_STATE_DEACTIVATING;
857                         timer = B_TIMER_DEACTIVATING;
858                         break;
859
860                         case B_STATE_REMOTE:
861                         /* bchannel is exported, so we re-import */
862                         message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
863                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
864                         add_trace("type", NULL, "remove");
865                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
866                         end_trace();
867                         state = B_STATE_IMPORTING;
868                         break;
869
870                         case B_STATE_DEACTIVATING:
871                         case B_STATE_IMPORTING:
872                         /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
873                         break;
874
875                         default:
876                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
877                 }
878                 break;
879
880                 case B_EVENT_DEACTIVATED:
881                 timer = 0;
882                 switch(state) {
883                         case B_STATE_IDLE:
884                         /* ignore due to deactivation confirm after unloading */
885                         break;
886
887                         case B_STATE_DEACTIVATING:
888                         _bchannel_destroy(mISDNport, i);
889                         state = B_STATE_IDLE;
890                         if (b_port) {
891                                 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
892                                 if (p_m_remote_ref) {
893                                         message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
894                                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
895                                         add_trace("type", NULL, "assign");
896                                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
897                                         end_trace();
898                                         state = B_STATE_EXPORTING;
899                                         mISDNport->b_remote_id[i] = p_m_remote_id;
900                                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
901                                 } else {
902                                         if (_bchannel_create(mISDNport, i)) {
903                                                 _bchannel_activate(mISDNport, i, 1, 0);
904                                                 state = B_STATE_ACTIVATING;
905                                                 timer = B_TIMER_ACTIVATING;
906                                         }
907                                 }
908                         }
909                         break;
910
911                         default:
912                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
913                 }
914                 break;
915
916                 case B_EVENT_IMPORTED:
917                 switch(state) {
918                         case B_STATE_IMPORTING:
919                         state = B_STATE_IDLE;
920                         mISDNport->b_remote_id[i] = 0;
921                         mISDNport->b_remote_ref[i] = 0;
922                         if (b_port) {
923                                 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
924                                 if (p_m_remote_ref) {
925                                         message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
926                                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
927                                         add_trace("type", NULL, "assign");
928                                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
929                                         end_trace();
930                                         state = B_STATE_EXPORTING;
931                                         mISDNport->b_remote_id[i] = p_m_remote_id;
932                                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
933                                 } else {
934                                         if (_bchannel_create(mISDNport, i)) {
935                                                 _bchannel_activate(mISDNport, i, 1, 0);
936                                                 state = B_STATE_ACTIVATING;
937                                                 timer = B_TIMER_ACTIVATING;
938                                         }
939                                 }
940                         }
941                         break;
942
943                         default:
944                         /* ignore, because not assigned */
945                         ;
946                 }
947                 break;
948
949                 case B_EVENT_TIMEOUT:
950                 timer = 0;
951                 switch(state) {
952                         case B_STATE_IDLE:
953                         /* ignore due to deactivation confirm after unloading */
954                         break;
955
956                         case B_STATE_ACTIVATING:
957                         _bchannel_activate(mISDNport, i, 1, 1);
958                         timer = B_TIMER_ACTIVATING;
959                         break;
960
961                         case B_STATE_DEACTIVATING:
962                         _bchannel_activate(mISDNport, i, 0, 1);
963                         timer = B_TIMER_DEACTIVATING;
964                         break;
965
966                         default:
967                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
968                 }
969                 break;
970
971                 default:
972                 PERROR("Illegal event %d, please correct.\n", event);
973         }
974
975         mISDNport->b_state[i] = state;
976         if (timer == 0)
977                 unsched_timer(&mISDNport->b_timer[i]);
978         else if (timer > 0)
979                 schedule_timer(&mISDNport->b_timer[i], timer, 0);
980 }
981
982
983
984
985 /*
986  * check for available channel and reserve+set it.
987  * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
988  * give exclusiv flag
989  * returns -(cause value) or x = channel x or 0 = no channel
990  * NOTE: no activation is done here
991  */
992 int PmISDN::seize_bchannel(int channel, int exclusive)
993 {
994         int i;
995
996         /* the channel is what we have */
997         if (p_m_b_channel == channel)
998                 return(channel);
999
1000         /* if channel already in use, release it */
1001         if (p_m_b_channel)
1002                 drop_bchannel();
1003
1004         /* if CHANNEL_NO */
1005         if (channel==CHANNEL_NO || channel==0)
1006                 return(0);
1007         
1008         /* is channel in range ? */
1009         if (channel==16
1010          || (channel>p_m_mISDNport->b_num && channel<16)
1011          || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1012                 return(-6); /* channel unacceptable */
1013
1014         /* request exclusive channel */
1015         if (exclusive && channel>0) {
1016                 i = channel-1-(channel>16);
1017                 if (p_m_mISDNport->b_port[i])
1018                         return(-44); /* requested channel not available */
1019                 goto seize;
1020         }
1021
1022         /* ask for channel */
1023         if (channel>0) {
1024                 i = channel-1-(channel>16);
1025                 if (p_m_mISDNport->b_port[i] == NULL)
1026                         goto seize;
1027         }
1028
1029         /* search for channel */
1030         i = 0;
1031         while(i < p_m_mISDNport->b_num) {
1032                 if (!p_m_mISDNport->b_port[i]) {
1033                         channel = i+1+(i>=15);
1034                         goto seize;
1035                 }
1036                 i++;
1037         }
1038         return(-34); /* no free channel */
1039
1040 seize:
1041         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1042
1043         /* link Port, set parameters */
1044         p_m_mISDNport->b_port[i] = this;
1045         p_m_b_index = i;
1046         p_m_b_channel = channel;
1047         p_m_b_exclusive = exclusive;
1048         p_m_mISDNport->b_mode[i] = p_m_b_mode;
1049
1050         /* reserve channel */
1051         if (!p_m_b_reserve) {
1052                 p_m_b_reserve = 1;
1053                 p_m_mISDNport->b_reserved++;
1054         }
1055
1056         return(channel);
1057 }
1058
1059 /*
1060  * drop reserved channel and unset it.
1061  * deactivation is also done
1062  */
1063 void PmISDN::drop_bchannel(void)
1064 {
1065         /* unreserve channel */
1066         if (p_m_b_reserve)
1067                 p_m_mISDNport->b_reserved--;
1068         p_m_b_reserve = 0;
1069
1070         /* if not in use */
1071         if (p_m_b_index < 0)
1072                 return;
1073         if (!p_m_b_channel)
1074                 return;
1075
1076         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1077
1078         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1079                 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1080         p_m_mISDNport->b_port[p_m_b_index] = NULL;
1081         p_m_mISDNport->b_mode[p_m_b_index] = 0;
1082         p_m_b_index = -1;
1083         p_m_b_channel = 0;
1084         p_m_b_exclusive = 0;
1085 }
1086
1087 /* process bchannel export/import message from join */
1088 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1089 {
1090         class Endpoint *epoint;
1091         class Port *port;
1092         class PmISDN *isdnport;
1093         struct mISDNport *mISDNport;
1094         int i, ii;
1095
1096         switch(type) {
1097                 case BCHANNEL_REQUEST:
1098                 /* find the port object for the join object ref */
1099                 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1100                         PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1101                         return;
1102                 }
1103                 if (!epoint->ep_portlist) {
1104                         PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1105                         return;
1106                 }
1107                 if (epoint->ep_portlist->next) {
1108                         PERROR("join %d has enpoint %d with more than one port. this shall not happen to remote joins.\n", joinremote->j_serial, epoint->ep_serial);
1109                 }
1110                 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1111                         PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1112                         return;
1113                 }
1114                 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1115                         PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1116                 }
1117                 isdnport = (class PmISDN *)port;
1118
1119                 /* assign */
1120                 if (isdnport->p_m_remote_id) {
1121                         PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1122                         break;
1123                 }
1124                 mISDNport = isdnport->p_m_mISDNport;
1125                 i = isdnport->p_m_b_index;
1126                 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1127                 add_trace("type", NULL, "export request");
1128                 end_trace();
1129                 isdnport->p_m_remote_ref = joinremote->j_remote_ref;
1130                 isdnport->p_m_remote_id = joinremote->j_remote_id;
1131                 if (mISDNport && i>=0) {
1132                         bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1133                 }
1134                 break;
1135
1136                 case BCHANNEL_RELEASE:
1137                 case BCHANNEL_ASSIGN_ACK:
1138                 case BCHANNEL_REMOVE_ACK:
1139                 /* find mISDNport for stack ID */
1140                 mISDNport = mISDNport_first;
1141                 while(mISDNport) {
1142                         i = 0;
1143                         ii = mISDNport->b_num;
1144                         while(i < ii) {
1145                                 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1146                                         break;
1147                                 i++;
1148                         }
1149                         if (i != ii)
1150                                 break;
1151                         mISDNport = mISDNport->next;
1152                 }
1153                 if (!mISDNport) {
1154                         PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1155                         break;
1156                 }
1157                 
1158                 if (type!=BCHANNEL_RELEASE) {
1159                         /* ack */
1160                         chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1161                         add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1162                         end_trace();
1163                         bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1164                 } else {
1165                         /* release */
1166                         isdnport = mISDNport->b_port[i];
1167                         chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1168                         add_trace("type", NULL, "import request");
1169                         end_trace();
1170                         if (isdnport) {
1171                                 isdnport->p_m_remote_ref = 0;
1172                                 isdnport->p_m_remote_id = 0;
1173                         }
1174                         bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1175                 }
1176                 break;
1177                 default:
1178                 PERROR("received wrong bchannel message type %d from remote\n", type);
1179         }
1180 }
1181
1182
1183 /*
1184  * handler
1185
1186 audio transmission procedure:
1187 -----------------------------
1188
1189 * priority
1190 three sources of audio transmission:
1191 - crypto-data high priority
1192 - tones high priority (also high)
1193 - remote-data low priority
1194
1195 * elapsed
1196 a variable that temporarily shows the number of samples elapsed since last transmission process.
1197 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1198
1199 * load
1200 a variable that is increased whenever data is transmitted.
1201 it is decreased while time elapses. it stores the number of samples that
1202 are currently loaded to dsp module.
1203 since clock in dsp module is the same clock for user space process, these 
1204 times have no skew.
1205
1206 * levels
1207 there are two levels:
1208 ISDN_LOAD will give the load that have to be kept in dsp.
1209 ISDN_MAXLOAD will give the maximum load before dropping.
1210
1211 * procedure for low priority data
1212 see txfromup() for procedure
1213 in short: remote data is ignored during high priority tones
1214
1215 * procedure for high priority data
1216 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1217 if no more data is available, load becomes empty again.
1218
1219 'load' variable:
1220 0                    ISDN_LOAD           ISDN_MAXLOAD
1221 +--------------------+----------------------+
1222 |                    |                      |
1223 +--------------------+----------------------+
1224
1225 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1226 0                    ISDN_LOAD           ISDN_MAXLOAD
1227 +--------------------+----------------------+
1228 |TTTTTTTTTTTTTTTTTTTT|                      |
1229 +--------------------+----------------------+
1230
1231 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1232 0                    ISDN_LOAD           ISDN_MAXLOAD
1233 +--------------------+----------------------+
1234 |TTTTTTTTTTTTTTTTTTTTRRRRR                  |
1235 +--------------------+----------------------+
1236
1237  */
1238 void PmISDN::update_load(void)
1239 {
1240         /* don't trigger load event if: */
1241         if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1242                 return;
1243
1244         /* don't trigger load event if event already active */
1245         if (p_m_loadtimer.active)
1246                 return;
1247
1248         schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1249 }
1250
1251 int load_timer(struct lcr_timer *timer, void *instance, int index)
1252 {
1253         class PmISDN *isdnport = (class PmISDN *)instance;
1254
1255         isdnport->load_tx();
1256
1257         return 0;
1258 }
1259
1260 void PmISDN::load_tx(void)
1261 {
1262         int elapsed = 0;
1263         int ret;
1264         struct timeval current_time;
1265
1266         /* get elapsed */
1267         gettimeofday(&current_time, NULL);
1268         if (p_m_last_tv_sec) {
1269                 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1270                         + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1271         }
1272         /* set clock of last process! */
1273         p_m_last_tv_sec = current_time.tv_sec;
1274         p_m_last_tv_msec = current_time.tv_usec/1000;
1275
1276         /* process only if we have samples and we are active */
1277         if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1278                 /* update load */
1279                 if (elapsed < p_m_load)
1280                         p_m_load -= elapsed;
1281                 else
1282                         p_m_load = 0;
1283
1284                 /* to send data, tone must be on */
1285                 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1286                  && (p_m_load < ISDN_LOAD) /* not too much load? */
1287                  && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1288                         int tosend = ISDN_LOAD - p_m_load, length; 
1289                         unsigned char buf[MISDN_HEADER_LEN+tosend];
1290                         struct mISDNhead *frm = (struct mISDNhead *)buf;
1291                         unsigned char *p = buf+MISDN_HEADER_LEN;
1292
1293                         /* copy inband signalling (e.g. used by ss5) */
1294                         if (p_m_inband_send_on && tosend) {
1295                                 tosend -= inband_send(p, tosend);
1296                         }
1297
1298                         /* copy crypto loops */
1299                         while (p_m_crypt_msg_loops && tosend) {
1300                                 /* how much do we have to send */
1301                                 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1302
1303                                 /* clip tosend */
1304                                 if (length > tosend)
1305                                         length = tosend;
1306
1307                                 /* copy message (part) to buffer */
1308                                 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1309
1310                                 /* new position */
1311                                 p_m_crypt_msg_current += length;
1312                                 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1313                                         /* next loop */
1314                                         p_m_crypt_msg_current = 0;
1315                                         p_m_crypt_msg_loops--;
1316                                         if (!p_m_crypt_msg_loops)
1317                                                 update_rxoff();
1318 //                                      puts("eine loop weniger");
1319                                 }
1320
1321                                 /* new length */
1322                                 tosend -= length;
1323                         }
1324
1325                         /* copy tones */
1326                         if (p_tone_name[0] && tosend) {
1327                                 tosend -= read_audio(p, tosend);
1328                         }
1329
1330                         /* send data */
1331                         if (ISDN_LOAD - p_m_load - tosend > 0) {
1332                                 frm->prim = PH_DATA_REQ;
1333                                 frm->id = 0;
1334                                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1335                                 if (ret <= 0)
1336                                         PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_sock[p_m_b_index].fd, ISDN_LOAD-p_m_load-tosend);
1337                                 p_m_load += ISDN_LOAD - p_m_load - tosend;
1338                         }
1339                 }
1340         }
1341
1342         if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1343                 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
1344         }
1345 }
1346
1347 /* handle timeouts */
1348 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1349 {
1350         class PmISDN *isdnport = (class PmISDN *)instance;
1351         struct lcr_msg *message;
1352
1353         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);
1354         /* send timeout to endpoint */
1355         message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1356         message->param.state = isdnport->p_state;
1357         message_put(message);
1358
1359         return 0;
1360 }
1361         
1362
1363 /*
1364  * whenever we get audio data from bchannel, we process it here
1365  */
1366 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1367 {
1368         unsigned int cont = *((unsigned int *)data);
1369         struct lcr_msg *message;
1370         unsigned char *p;
1371         int l;
1372
1373         if (hh->prim == PH_CONTROL_IND) {
1374                 if (len < 4) {
1375                         PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1376                         return;
1377                 }
1378                 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1379                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1380                         add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1381                         if (!p_m_dtmf)
1382                                 add_trace("info", NULL, "DTMF is disabled");
1383                         end_trace();
1384                         if (!p_m_dtmf)
1385                                 return;
1386                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1387                         message->param.dtmf = cont & DTMF_TONE_MASK;
1388                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  DTMF digit '%c'\n", p_name, message->param.dtmf);
1389                         message_put(message);
1390                         return;
1391                 }
1392                 switch(cont) {
1393                         case DSP_BF_REJECT:
1394                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1395                         add_trace("DSP-CRYPT", NULL, "error");
1396                         end_trace();
1397                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1398                         message->param.crypt.type = CC_ERROR_IND;
1399                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  reject of blowfish.\n", p_name);
1400                         message_put(message);
1401                         break;
1402
1403                         case DSP_BF_ACCEPT:
1404                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1405                         add_trace("DSP-CRYPT", NULL, "ok");
1406                         end_trace();
1407                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1408                         message->param.crypt.type = CC_ACTBF_CONF;
1409                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  accept of blowfish.\n", p_name);
1410                         message_put(message);
1411                         break;
1412
1413                         default:
1414                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1415                         add_trace("unknown", NULL, "0x%x", cont);
1416                         end_trace();
1417                 }
1418                 return;
1419         }
1420         if (hh->prim == PH_CONTROL_IND) {
1421                 switch(hh->id) {
1422                         default:
1423                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1424                         add_trace("unknown", NULL, "0x%x", hh->id);
1425                         end_trace();
1426                 }
1427                 return;
1428         }
1429         if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1430                 if (!p_m_txdata) {
1431                         /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1432                         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1433                         return;
1434                 }
1435                 /* see below (same condition) */
1436                 if (p_state!=PORT_STATE_CONNECT
1437                          && !p_m_mISDNport->tones)
1438                         return;
1439 //              printf(".");fflush(stdout);return;
1440                 if (p_record)
1441                         record(data, len, 1); // from up
1442                 return;
1443         }
1444         if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1445                 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1446                 return;
1447         }
1448
1449         /* inband is processed */
1450         if (p_m_inband_receive_on)
1451                 inband_receive(data, len);
1452
1453         /* send to remote, if bridged */
1454         bridge_tx(data, len);
1455
1456         /* calls will not process any audio data unless
1457          * the call is connected OR tones feature is enabled.
1458          */
1459 #ifndef DEBUG_COREBRIDGE
1460         if (p_state!=PORT_STATE_CONNECT
1461          && !p_m_mISDNport->tones)
1462                 return;
1463 #endif
1464
1465 #if 0
1466         /* the bearer capability must be audio in order to send and receive
1467          * audio prior or after connect.
1468          */
1469         if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1470                 return;
1471 #endif
1472
1473         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1474         if (p_m_rxoff) {
1475                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1476                 return;
1477         }
1478
1479         /* record data */
1480         if (p_record)
1481                 record(data, len, 0); // from down
1482
1483         /* randomize and listen to crypt message if enabled */
1484         if (p_m_crypt_listen) {
1485                 /* the noisy randomizer */
1486                 p = data;
1487                 l = len;
1488                 while(l--)
1489                         mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1490
1491                 cryptman_listen_bch(data, len);
1492         }
1493 }
1494
1495
1496 /*
1497  * set echotest
1498  */
1499 void PmISDN::set_echotest(int echo)
1500 {
1501         if (p_m_echo != echo) {
1502                 p_m_echo = echo;
1503                 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1504                 if (p_m_b_channel)
1505                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1506                                 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);
1507         }
1508 }
1509
1510 /*
1511  * set tone
1512  */
1513 void PmISDN::set_tone(const char *dir, const char *tone)
1514 {
1515         int id = TONE_OFF;
1516         int dsp = DSP_NONE;
1517
1518         /* if no directory is given (by extension), we use interface.conf or options.conf */
1519         if (!dir || !dir[0]) {
1520                 if (p_m_mISDNport->ifport->tones_dir[0])
1521                         dir = p_m_mISDNport->ifport->tones_dir;
1522                 else if (options.tones_dir[0])
1523                         dir = options.tones_dir;
1524         }
1525
1526         if (!tone)
1527                 tone = "";
1528         PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1529         if (!tone[0]) {
1530                 id = TONE_OFF;
1531                 goto setdsp;
1532         }
1533
1534         /* check for dsp tones */
1535         if (!strcmp(dir, "american"))
1536                 dsp = DSP_AMERICAN;
1537         if (!strcmp(dir, "german"))
1538                 dsp = DSP_GERMAN;
1539         if (!strcmp(dir, "oldgerman"))
1540                 dsp = DSP_OLDGERMAN;
1541
1542         /* check if we NOT really have to use a dsp-tone */
1543         if (dsp == DSP_NONE) {
1544                 nodsp:
1545                 if (p_m_tone)
1546                 if (p_m_b_index > -1)
1547                 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) {
1548                         PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1549                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1550                 }
1551                 p_m_tone = 0;
1552                 Port::set_tone(dir, tone);
1553                 return;
1554         }
1555
1556         /* now we USE dsp-tone, convert name */
1557         if (!strcmp(tone, "dialtone")) {
1558                 switch(dsp) {
1559                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1560                 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1561                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1562                 }
1563         } else if (!strcmp(tone, "dialpbx")) {
1564                 switch(dsp) {
1565                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1566                 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1567                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1568                 }
1569         } else if (!strcmp(tone, "ringing")) {
1570                 switch(dsp) {
1571                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1572                 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1573                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1574                 }
1575         } else if (!strcmp(tone, "ringpbx")) {
1576                 switch(dsp) {
1577                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1578                 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1579                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1580                 }
1581         } else if (!strcmp(tone, "busy")) {
1582                 busy:
1583                 switch(dsp) {
1584                 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1585                 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1586                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1587                 }
1588         } else if (!strcmp(tone, "release")) {
1589                 hangup:
1590                 switch(dsp) {
1591                 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1592                 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1593                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1594                 }
1595         } else if (!strcmp(tone, "cause_10"))
1596                 goto hangup;
1597         else if (!strcmp(tone, "cause_11"))
1598                 goto busy;
1599         else if (!strcmp(tone, "cause_22")) {
1600                 switch(dsp) {
1601                 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1602                 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1603                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1604                 }
1605         } else if (!strncmp(tone, "cause_", 6))
1606                 id = TONE_SPECIAL_INFO;
1607         else
1608                 id = TONE_OFF;
1609
1610         /* if we have a tone that is not supported by dsp */
1611         if (id==TONE_OFF && tone[0])
1612                 goto nodsp;
1613
1614         setdsp:
1615         if (p_m_tone != id) {
1616                 /* set new tone */
1617                 p_m_tone = id;
1618                 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1619                 if (p_m_b_index > -1)
1620                 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)
1621                         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);
1622         }
1623         /* turn user-space tones off in cases of no tone OR dsp tone */
1624         Port::set_tone("",NULL);
1625 }
1626
1627
1628 /* MESSAGE_mISDNSIGNAL */
1629 //extern struct lcr_msg *dddebug;
1630 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1631 {
1632         int oldconf, newconf;
1633         switch(param->mISDNsignal.message) {
1634                 case mISDNSIGNAL_VOLUME:
1635                 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1636                         p_m_tx_gain = param->mISDNsignal.tx_gain;
1637                         PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1638                         if (p_m_b_index > -1)
1639                         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)
1640                                 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);
1641                 } else
1642                         PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1643                 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1644                         p_m_rx_gain = param->mISDNsignal.rx_gain;
1645                         PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1646                         if (p_m_b_index > -1)
1647                         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)
1648                                 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);
1649                 } else
1650                         PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1651                 break;
1652
1653                 case mISDNSIGNAL_CONF:
1654                 oldconf = p_m_mute?0:p_m_conf;
1655                 p_m_conf = param->mISDNsignal.conf;
1656                 newconf = p_m_mute?0:p_m_conf;
1657                 set_conf(oldconf, newconf);
1658                 break;
1659
1660                 case mISDNSIGNAL_DELAY:
1661                 if (p_m_delay != param->mISDNsignal.delay) {
1662                         p_m_delay = param->mISDNsignal.delay;
1663                         PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1664                         if (p_m_b_index > -1)
1665                         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)
1666                                 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);
1667                 } else
1668                         PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1669                 break;
1670
1671                 default:
1672                 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1673         }
1674 }
1675
1676 /* MESSAGE_CRYPT */
1677 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1678 {
1679         struct lcr_msg *message;
1680
1681         switch(param->crypt.type) {
1682                 case CC_ACTBF_REQ:           /* activate blowfish */
1683                 p_m_crypt = 1;
1684                 p_m_crypt_key_len = param->crypt.len;
1685                 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1686                         PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1687                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1688                         message->param.crypt.type = CC_ERROR_IND;
1689                         message_put(message);
1690                         break;
1691                 }
1692                 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1693                 crypt_off:
1694                 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1695                 if (p_m_b_index > -1)
1696                 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)
1697                         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);
1698                 break;
1699
1700                 case CC_DACT_REQ:            /* deactivate session encryption */
1701                 p_m_crypt = 0;
1702                 goto crypt_off;
1703                 break;
1704
1705                 case CR_LISTEN_REQ:          /* start listening to messages */
1706                 p_m_crypt_listen = 1;
1707                 update_rxoff();
1708                 p_m_crypt_listen_state = 0;
1709                 break;
1710
1711                 case CR_UNLISTEN_REQ:        /* stop listening to messages */
1712                 p_m_crypt_listen = 0;
1713                 update_rxoff();
1714                 break;
1715
1716                 case CR_MESSAGE_REQ:         /* send message */
1717                 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1718                 if (!p_m_crypt_msg_len) {
1719                         PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1720                         break;
1721                 }
1722                 p_m_crypt_msg_current = 0; /* reset */
1723                 p_m_crypt_msg_loops = 6; /* enable */
1724                 update_rxoff();
1725                 update_load();
1726 #if 0
1727                 /* disable txmix, or we get corrupt data due to audio process */
1728                 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1729                         PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1730                         ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1731                 }
1732 #endif
1733                 break;
1734
1735                 default:
1736                 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1737         }
1738
1739 }
1740
1741 /*
1742  * endpoint sends messages to the port
1743  */
1744 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1745 {
1746         if (Port::message_epoint(epoint_id, message_id, param)) {
1747                 if (message_id == MESSAGE_BRIDGE)
1748                         update_rxoff();
1749                 return 1;
1750         }
1751
1752         switch(message_id) {
1753                 case MESSAGE_mISDNSIGNAL: /* user command */
1754                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1755                 message_mISDNsignal(epoint_id, message_id, param);
1756                 return 1;
1757
1758                 case MESSAGE_CRYPT: /* crypt control command */
1759                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1760                 message_crypt(epoint_id, message_id, param);
1761                 return 1;
1762         }
1763
1764         return 0;
1765 }
1766
1767 void PmISDN::update_rxoff(void)
1768 {
1769         int tx_dejitter = 0;
1770
1771         /* call bridges in user space OR crypto OR recording */
1772         if (p_bridge || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1773                 /* rx IS required */
1774                 if (p_m_rxoff) {
1775                         /* turn on RX */
1776                         p_m_rxoff = 0;
1777                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1778                         if (p_m_b_index > -1)
1779                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1780                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1781                 }
1782         } else {
1783                 /* rx NOT required */
1784                 if (!p_m_rxoff) {
1785                         /* turn off RX */
1786                         p_m_rxoff = 1;
1787                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1788                         if (p_m_b_index > -1)
1789                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1790                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1791                 }
1792         }
1793         /* recording */
1794         if (p_record) {
1795                 /* txdata IS required */
1796                 if (!p_m_txdata) {
1797                         /* turn on RX */
1798                         p_m_txdata = 1;
1799                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1800                         if (p_m_b_index > -1)
1801                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1802                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1803                 }
1804         } else {
1805                 /* txdata NOT required */
1806                 if (p_m_txdata) {
1807                         /* turn off RX */
1808                         p_m_txdata = 0;
1809                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1810                         if (p_m_b_index > -1)
1811                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1812                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1813                 }
1814         }
1815         /* dejitter on bridge */
1816         if (p_bridge)
1817                 tx_dejitter = 1;
1818         if (p_m_tx_dejitter != tx_dejitter) {
1819                 p_m_tx_dejitter = tx_dejitter;
1820                 PDEBUG(DEBUG_BCHANNEL, "we change dejitter mode to delay=%d.\n", p_m_tx_dejitter);
1821                 if (p_m_b_index > -1)
1822                         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)
1823                                 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);
1824         }
1825 }
1826
1827 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1828 {
1829         struct mISDNport *mISDNport;
1830         struct mbuffer *mb;
1831         struct l3_msg *l3m;
1832         char byte;
1833         int ret;
1834
1835         /* unset global semaphore */
1836         upqueue_avail = 0;
1837         // with a very small incident, upqueue_avail may be set by mISDN thread and
1838         // another byte may be sent to the pipe, which causes a call to this function
1839         // again with nothing in the upqueue. this is no problem.
1840         ret = read(fd->fd, &byte, 1);
1841
1842         /* process all ports */
1843         mISDNport = mISDNport_first;
1844         while(mISDNport) {
1845                 /* handle queued up-messages (d-channel) */
1846                 if (!mISDNport->isloopback) {
1847                         while ((mb = mdequeue(&mISDNport->upqueue))) {
1848                                 l3m = &mb->l3;
1849                                 switch(l3m->type) {
1850                                         case MPH_ACTIVATE_IND:
1851                                         if (mISDNport->l1link != 1) {
1852                                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1853                                                 end_trace();
1854                                                 mISDNport->l1link = 1;
1855                                         }
1856                                         break;
1857                 
1858                                         case MPH_DEACTIVATE_IND:
1859                                         if (mISDNport->l1link != 0) {
1860                                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1861                                                 end_trace();
1862                                                 mISDNport->l1link = 0;
1863                                         }
1864                                         break;
1865
1866                                         case MPH_INFORMATION_IND:
1867                                         PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1868                                         switch (l3m->pid) {
1869                                                 case L1_SIGNAL_LOS_ON:
1870                                                 mISDNport->los = 1;
1871                                                 break;
1872                                                 case L1_SIGNAL_LOS_OFF:
1873                                                 mISDNport->los = 0;
1874                                                 break;
1875                                                 case L1_SIGNAL_AIS_ON:
1876                                                 mISDNport->ais = 1;
1877                                                 break;
1878                                                 case L1_SIGNAL_AIS_OFF:
1879                                                 mISDNport->ais = 0;
1880                                                 break;
1881                                                 case L1_SIGNAL_RDI_ON:
1882                                                 mISDNport->rdi = 1;
1883                                                 break;
1884                                                 case L1_SIGNAL_RDI_OFF:
1885                                                 mISDNport->rdi = 0;
1886                                                 break;
1887                                                 case L1_SIGNAL_SLIP_TX:
1888                                                 mISDNport->slip_tx++;
1889                                                 break;
1890                                                 case L1_SIGNAL_SLIP_RX:
1891                                                 mISDNport->slip_rx++;
1892                                                 break;
1893                                         }
1894                                         break;
1895
1896                                         case MT_L2ESTABLISH:
1897                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1898                                         add_trace("tei", NULL, "%d", l3m->pid);
1899                                         end_trace();
1900                                         mISDNport->l2link = 1;
1901                                         if (l3m->pid < 128)
1902                                                 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1903                                         if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1904                                                 if (mISDNport->l2establish.active) {
1905                                                         unsched_timer(&mISDNport->l2establish);
1906                                                         PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1907                                                 }
1908                                         }
1909                                         break;
1910
1911                                         case MT_L2RELEASE:
1912                                         if (l3m->pid < 128)
1913                                                 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1914                                         if (!mISDNport->l2establish.active) {
1915                                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1916                                                 add_trace("tei", NULL, "%d", l3m->pid);
1917                                                 end_trace();
1918                                                 /* down if not nt-ptmp */ 
1919                                                 if (!mISDNport->ntmode || mISDNport->ptp)
1920                                                         mISDNport->l2link = 0;
1921                                         }
1922                                         if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1923                                                 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1924                                                         PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1925                                                         schedule_timer(&mISDNport->l2establish, 5, 0);
1926                                                         mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1927                                                 }
1928                                         }
1929                                         break;
1930
1931                                         default:
1932                                         /* l3-data is sent to LCR */
1933                                         stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1934                                 }
1935                                 /* free message */
1936                                 free_l3_msg(l3m);
1937                         }
1938                 }
1939                 mISDNport = mISDNport->next;
1940         }
1941         return 0;
1942 }
1943
1944 /* l2 establish timer fires */
1945 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1946 {
1947         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1948
1949         if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1950                 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1951                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1952                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1953         }
1954
1955         return 0;
1956 }
1957
1958 /* handle frames from bchannel */
1959 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1960 {
1961         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1962         unsigned char buffer[2048+MISDN_HEADER_LEN];
1963         struct mISDNhead *hh = (struct mISDNhead *)buffer;
1964         int ret;
1965
1966         ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1967         if (ret < 0) {
1968                 PERROR("read error frame, errno %d\n", errno);
1969                 return 0;
1970         }
1971         if (ret < (int)MISDN_HEADER_LEN) {
1972                 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1973                 return 0;
1974         }
1975         switch(hh->prim) {
1976                 /* we don't care about confirms, we use rx data to sync tx */
1977                 case PH_DATA_CNF:
1978                 break;
1979
1980                 /* we receive audio data, we respond to it AND we send tones */
1981                 case PH_DATA_IND:
1982                 case DL_DATA_IND:
1983                 case PH_DATA_REQ:
1984                 case DL_DATA_REQ:
1985                 case PH_CONTROL_IND:
1986                 if (mISDNport->b_port[i])
1987                         mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1988                 else
1989                         PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1990                 break;
1991
1992                 case PH_ACTIVATE_IND:
1993                 case DL_ESTABLISH_IND:
1994                 case PH_ACTIVATE_CNF:
1995                 case DL_ESTABLISH_CNF:
1996                 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1997                 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1998                 break;
1999
2000                 case PH_DEACTIVATE_IND:
2001                 case DL_RELEASE_IND:
2002                 case PH_DEACTIVATE_CNF:
2003                 case DL_RELEASE_CNF:
2004                 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2005                 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2006                 break;
2007
2008                 default:
2009                 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2010         }
2011
2012         return 0;
2013 }
2014
2015 /* process timer events for bchannel handling */
2016 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2017 {
2018         struct mISDNport *mISDNport = (struct mISDNport *)instance;
2019
2020         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2021
2022         return 0;
2023 }
2024
2025
2026 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2027 {
2028         /* IMPORTAINT:
2029          *
2030          * l3m must be queued, except for MT_ASSIGN
2031          *
2032          */
2033         struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2034         struct mbuffer *mb;
2035
2036 #ifdef OLD_MT_ASSIGN
2037         /* special MT_ASSIGN handling:
2038          *
2039          * if we request a PID from mlayer, we always do it while lcr is locked.
2040          * therefore we must check the MT_ASSIGN reply first before we lock.
2041          * this is because the MT_ASSIGN reply is received with the requesting
2042          * process, not by the mlayer thread!
2043          * this means, that the reply is sent during call of the request.
2044          * we must check if we get a reply and we know that we lcr is currently
2045          * locked.
2046          */
2047         if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2048                 /* let's do some checking if someone changes stack behaviour */
2049                 if (mt_assign_pid != 0)
2050                         FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2051                 mt_assign_pid = pid;
2052                 return(0);
2053         }
2054 #endif
2055         /* queue message, create, if required */
2056         if (!l3m) {
2057                 l3m = alloc_l3_msg();
2058                 if (!l3m)
2059                         FATAL("No memory for layer 3 message\n");
2060         }
2061         mb = container_of(l3m, struct mbuffer, l3);
2062         l3m->type = cmd;
2063         l3m->pid = pid;
2064         mqueue_tail(&mISDNport->upqueue, mb);
2065         if (!upqueue_avail) {
2066                 // multiple threads may cause multiple calls of this section, but this
2067                 // results only in multiple processing of the upqueue read.
2068                 // this is no problem.
2069                 upqueue_avail = 1;
2070                 char byte = 0;
2071                 int ret;
2072                 ret = write(upqueue_pipe[1], &byte, 1);
2073         }
2074         return 0;
2075 }
2076
2077 int mISDN_getportbyname(int sock, int cnt, char *portname)
2078 {
2079         struct mISDN_devinfo devinfo;
2080         int port = 0, ret;
2081
2082         /* resolve name */
2083         while (port < cnt) {
2084                 devinfo.id = port;
2085                 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2086                 if (ret < 0)
2087                         return ret;
2088                 if (!strcasecmp(devinfo.name, portname))
2089                         break;
2090                 port++;
2091         }
2092         if (port == cnt)
2093                 return -EIO;
2094
2095         return (port);
2096 }
2097
2098 /*
2099  * global function to add a new card (port)
2100  */
2101 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2102 {
2103         int ret;
2104         struct mISDNport *mISDNport, **mISDNportp;
2105         int port = ifport->portnum;
2106         int ptp = ifport->ptp;
2107         int force_nt = ifport->nt;
2108         int l1hold = ifport->l1hold;
2109         int l2hold = ifport->l2hold;
2110         int loop = 0;
2111         int ss5 = ifport->ss5;
2112         int i, cnt;
2113         int pri, bri, pots;
2114         int nt, te;
2115 //      struct mlayer3 *ml3;
2116         struct mISDN_devinfo devinfo;
2117         unsigned int protocol, prop;
2118
2119         loop = 0;
2120 //printf("%s == %s\n", ifport->portname, options.loopback_int);
2121         if (!strcmp(ifport->portname, options.loopback_lcr))
2122                 loop = 1;
2123
2124         if (loop) {
2125                 if (mISDNloop_open())
2126                         return NULL;
2127         }
2128
2129         /* check port counts */
2130         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2131         if (ret < 0) {
2132                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2133                 return(NULL);
2134         }
2135
2136         if (cnt <= 0) {
2137                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2138                 return(NULL);
2139         }
2140         if (port < 0) {
2141                 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2142                 if (port < 0) {
2143                         if (loop)
2144                                 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
2145                         else
2146                                 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2147                         return(NULL);
2148                 }
2149                 // note: 'port' has still the port number
2150         }
2151         if (port>cnt || port<0) {
2152                 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2153                 return(NULL);
2154         }
2155
2156         /* get port attributes */
2157         pri = bri = pots = nt = te = 0;
2158         devinfo.id = port;
2159         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2160         if (ret < 0) {
2161                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2162                 return(NULL);
2163         }
2164         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2165                 bri = 1;
2166                 te = 1;
2167         }
2168         if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2169                 bri = 1;
2170                 nt = 1;
2171         }
2172         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2173                 pri = 1;
2174                 te = 1;
2175         }
2176         if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2177                 pri = 1;
2178                 nt = 1;
2179         }
2180 #ifdef ISDN_P_FXS
2181         if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2182                 pots = 1;
2183                 te = 1;
2184         }
2185 #endif
2186 #ifdef ISDN_P_FXO
2187         if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2188                 pots = 1;
2189                 nt = 1;
2190         }
2191 #endif
2192         if (force_nt && !nt) {
2193                 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2194                 return(NULL);
2195         }
2196         if (bri && pri) {
2197                 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2198                 return(NULL);
2199         }
2200         if (pots && !bri && !pri) {
2201                 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2202                 return(NULL);
2203         }
2204         if (!bri && !pri) {
2205                 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2206                 return(NULL);
2207         }
2208         if (!nt && !te) {
2209                 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2210                 return(NULL);
2211         }
2212         /* set NT by turning off TE */
2213         if (force_nt && nt)
2214                 te = 0;
2215         /* if TE an NT is supported (and not forced to NT), turn off NT */
2216         if (te && nt)
2217                 nt = 0;
2218
2219         /* check for double use of port */
2220         if (nt) {
2221                 mISDNport = mISDNport_first;
2222                 while(mISDNport) {
2223                         if (mISDNport->portnum == port)
2224                                 break;
2225                         mISDNport = mISDNport->next;
2226                 }
2227                 if (mISDNport) {
2228                         PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2229                         return(NULL);
2230                 }
2231         }
2232
2233         /* check for continous channelmap with no bchannel on slot 16 */
2234         if (test_channelmap(0, devinfo.channelmap)) {
2235                 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2236                 return(NULL);
2237         }
2238         i = 1;
2239         while(i < (int)devinfo.nrbchan + 1) {
2240                 if (i == 16) {
2241                         if (test_channelmap(i, devinfo.channelmap)) {
2242                                 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2243                                 return(NULL);
2244                         }
2245                 } else {
2246                         if (!test_channelmap(i, devinfo.channelmap)) {
2247                                 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2248                                 return(NULL);
2249                         }
2250                 }
2251                 i++;
2252         }
2253
2254         /* add mISDNport structure */
2255         mISDNportp = &mISDNport_first;
2256         while(*mISDNportp)
2257                 mISDNportp = &((*mISDNportp)->next);
2258         mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2259         add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2260         if (loop | ss5) {
2261                 /* loop/ss5 link is always active */
2262                 mISDNport->l1link = 1;
2263                 mISDNport->l2link = 1;
2264         } else {
2265                 mISDNport->l1link = -1;
2266                 mISDNport->l2link = -1;
2267         }
2268         mISDNport->isloopback = loop;
2269         pmemuse++;
2270         *mISDNportp = mISDNport;
2271
2272         /* if pri, must set PTP */
2273         if (pri)
2274                 ptp = 1;
2275
2276         /* set ss5 params */
2277         if (ss5) {
2278                 /* try to keep interface enabled */
2279                 l1hold = 1;
2280                 l2hold = 0;
2281         }
2282         /* set l2hold */
2283         switch (l2hold) {
2284                 case -1: // off
2285                 l2hold = 0;
2286                 break;
2287                 case 1: // on
2288                 l2hold = 1;
2289                 break;
2290                 default:
2291                 if (ptp)
2292                         l2hold = 1;
2293                 else
2294                         l2hold = 0;
2295                 break;
2296         }
2297                 
2298         /* allocate ressources of port */
2299         protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2300         prop = (1 << MISDN_FLG_L2_CLEAN);
2301         if (ptp) // ptp forced
2302                prop |= (1 << MISDN_FLG_PTP);
2303         if (nt) // supports hold/retrieve on nt-mode
2304                prop |= (1 << MISDN_FLG_NET_HOLD);
2305         if (l1hold) // supports layer 1 hold
2306                prop |= (1 << MISDN_FLG_L1_HOLD);
2307         if (l2hold) // supports layer 2 hold
2308                prop |= (1 << MISDN_FLG_L2_HOLD);
2309         /* open layer 3 and init upqueue */
2310         if (loop) {
2311                 unsigned long on = 1;
2312                 struct sockaddr_mISDN addr;
2313
2314                 if (devinfo.nrbchan < 8) {
2315                         printf("loop port %d has a low number of bchannels. (only %d) remember that all interfaces that requires a loopback could run out of channels\n", port, devinfo.nrbchan);
2316 //                      mISDNport_close(mISDNport);
2317 //                      return(NULL);
2318                 }
2319
2320                 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
2321                         PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
2322                         mISDNport_close(mISDNport);
2323                         return(NULL);
2324                 }
2325                 /* set nonblocking io */
2326                 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2327                         PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
2328                         mISDNport_close(mISDNport);
2329                         return(NULL);
2330                 }
2331                 /* bind socket to dchannel */
2332                 memset(&addr, 0, sizeof(addr));
2333                 addr.family = AF_ISDN;
2334                 addr.dev = port;
2335                 addr.channel = 0;
2336                 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2337                         PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
2338                         mISDNport_close(mISDNport);
2339                         return(NULL);
2340                 }
2341         } else {
2342                 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2343                 mqueue_init(&mISDNport->upqueue);
2344                 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2345                 if (!mISDNport->ml3) {
2346                         mqueue_purge(&mISDNport->upqueue);
2347                         PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2348                         start_trace(port,
2349                                 ifport->interface,
2350                                 NULL,
2351                                 NULL,
2352                                 DIRECTION_NONE,
2353                                 CATEGORY_CH,
2354                                 0,
2355                                 "PORT (open failed)");
2356                         end_trace();
2357                         mISDNport_close(mISDNport);
2358                         return(NULL);
2359                 }
2360         }
2361
2362         SCPY(mISDNport->name, devinfo.name);
2363         mISDNport->b_num = devinfo.nrbchan;
2364         mISDNport->portnum = port;
2365         mISDNport->ntmode = nt;
2366         mISDNport->tespecial = ifport->tespecial;
2367         mISDNport->pri = pri;
2368         mISDNport->ptp = ptp;
2369         mISDNport->l1hold = l1hold;
2370         mISDNport->l2hold = l2hold;
2371         mISDNport->ss5 = ss5;
2372         PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2373         i = 0;
2374         while(i < mISDNport->b_num) {
2375                 mISDNport->b_state[i] = B_STATE_IDLE;
2376                 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2377                 i++;
2378         }
2379
2380         /* if ptp, pull up the link */
2381         if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2382                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2383                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2384                 add_trace("tei", NULL, "%d", 0);
2385                 end_trace();
2386                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2387         }
2388
2389         /* for nt-mode ptmp the link is always up */
2390         if (mISDNport->ntmode && !mISDNport->ptp)
2391                 mISDNport->l2link = 1;
2392
2393         PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2394
2395         start_trace(mISDNport->portnum,
2396                     ifport->interface,
2397                     NULL,
2398                     NULL,
2399                     DIRECTION_NONE,
2400                     CATEGORY_CH,
2401                     0,
2402                     "PORT (open)");
2403         add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2404         add_trace("channels", NULL, "%d", mISDNport->b_num);
2405         if (mISDNport->ss5)
2406                 add_trace("ccitt#5", NULL, "enabled");
2407         end_trace();
2408
2409         return(mISDNport);
2410 }
2411
2412
2413 /*
2414  * load static port instances, if required by mISDNport
2415  */
2416 void mISDNport_static(struct mISDNport *mISDNport)
2417 {
2418         int i;
2419
2420         i = 0;
2421         while(i < mISDNport->b_num) {
2422 #ifdef WITH_SS5
2423                 if (mISDNport->ss5)
2424                         ss5_create_channel(mISDNport, i);
2425 #endif
2426                 i++;
2427         }
2428 }
2429
2430
2431 /*
2432  * function to free ALL cards (ports)
2433  */
2434 void mISDNport_close_all(void)
2435 {
2436         /* free all ports */
2437         while(mISDNport_first)
2438                 mISDNport_close(mISDNport_first);
2439 }
2440
2441 /*
2442  * free only one port
2443  */
2444 void mISDNport_close(struct mISDNport *mISDNport)
2445 {
2446         struct mISDNport **mISDNportp;
2447         class Port *port;
2448         class PmISDN *isdnport;
2449         int i;
2450
2451         /* remove all port instance that are linked to this mISDNport */
2452         again:
2453         port = port_first;
2454         while(port) {
2455                 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2456                         isdnport = (class PmISDN *)port;
2457                         if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2458                                 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2459                                 delete isdnport;
2460                                 goto again;
2461                         }
2462                 }
2463                 port = port->next;
2464         }
2465
2466         /* only if we are already part of interface */
2467         if (mISDNport->ifport) {
2468                 start_trace(mISDNport->portnum,
2469                             mISDNport->ifport->interface,
2470                             NULL,
2471                             NULL,
2472                             DIRECTION_NONE,
2473                             CATEGORY_CH,
2474                             0,
2475                             "PORT (close)");
2476                 end_trace();
2477         }
2478
2479         /* free bchannels */
2480         i = 0;
2481         while(i < mISDNport->b_num) {
2482                 if (mISDNport->b_sock[i].inuse) {
2483                         _bchannel_destroy(mISDNport, i);
2484                         PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2485                 }
2486                 if (mISDNport->b_timer[i].inuse) {
2487                         del_timer(&mISDNport->b_timer[i]);
2488                 }
2489                 i++;
2490         }
2491         del_timer(&mISDNport->l2establish);
2492
2493         /* close layer 3, if open */
2494         if (!mISDNport->isloopback && mISDNport->ml3) {
2495                 close_layer3(mISDNport->ml3);
2496         }
2497
2498         /* close gsm socket, if open */
2499         if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
2500                 close(mISDNport->lcr_sock);
2501         }
2502
2503         /* purge upqueue */
2504         if (!mISDNport->isloopback)
2505                 mqueue_purge(&mISDNport->upqueue);
2506
2507         /* remove from list */
2508         mISDNportp = &mISDNport_first;
2509         while(*mISDNportp) {
2510                 if (*mISDNportp == mISDNport) {
2511                         *mISDNportp = (*mISDNportp)->next;
2512                         mISDNportp = NULL;
2513                         break;
2514                 }
2515                 mISDNportp = &((*mISDNportp)->next);
2516         }
2517
2518         if (mISDNportp)
2519                 FATAL("mISDNport not in list\n");
2520         
2521         FREE(mISDNport, sizeof(struct mISDNport));
2522         pmemuse--;
2523
2524 }
2525
2526
2527 /*
2528  * enque data from upper buffer
2529  */
2530 int PmISDN::bridge_rx(unsigned char *data, int length)
2531 {
2532         unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2533         struct mISDNhead *hh = (struct mISDNhead *)buf;
2534         int ret;
2535
2536         if (p_m_b_index < 0)
2537                 return -EIO;
2538         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2539                 return -EINVAL;
2540
2541         /* check if high priority tones exist
2542          * ignore data in this case
2543          */
2544         if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2545                 return -EBUSY;
2546
2547         /* preload procedure
2548          * if transmit buffer in DSP module is empty,
2549          * preload it to DSP_LOAD to prevent jitter gaps.
2550          */
2551         if (p_m_load == 0 && ISDN_LOAD > 0) {
2552                 hh->prim = PH_DATA_REQ; 
2553                 hh->id = 0;
2554                 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2555                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2556                 if (ret <= 0)
2557                         PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2558                 p_m_load += ISDN_LOAD;
2559                 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
2560         }
2561
2562         /* drop if load would exceed ISDN_MAXLOAD
2563          * this keeps the delay not too high
2564          */
2565         if (p_m_load+length > ISDN_MAXLOAD)
2566                 return -EINVAL;
2567
2568         /* make and send frame */
2569         hh->prim = PH_DATA_REQ;
2570         hh->id = 0;
2571         memcpy(buf+MISDN_HEADER_LEN, data, length);
2572         ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2573         if (ret <= 0)
2574                 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2575         p_m_load += length;
2576
2577         return 0;
2578 }
2579
2580 int PmISDN::inband_send(unsigned char *buffer, int len)
2581 {
2582         PERROR("this function must be derived to function!\n");
2583         return 0;
2584 }
2585
2586 void PmISDN::inband_send_on(void)
2587 {
2588         PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2589         p_m_inband_send_on = 1;
2590         /* trigger inband transmit */
2591         update_load();
2592 }
2593
2594 void PmISDN::inband_send_off(void)
2595 {
2596         PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2597         p_m_inband_send_on = 0;
2598 }
2599
2600 void PmISDN::inband_receive(unsigned char *buffer, int len)
2601 {
2602 //
2603 //      if (len >= SS5_DECODER_NPOINTS)
2604 //              ss5_decode(buffer, SS5_DECODER_NPOINTS);
2605         PERROR("this function must be derived to function!\n");
2606 }
2607
2608 void PmISDN::inband_receive_on(void)
2609 {
2610         /* this must work during constructor, see ss5.cpp */
2611         PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2612         p_m_inband_receive_on = 1;
2613         update_rxoff();
2614 }
2615
2616 void PmISDN::inband_receive_off(void)
2617 {
2618         PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2619         p_m_inband_receive_on = 0;
2620         update_rxoff();
2621 }
2622
2623 void PmISDN::mute_on(void)
2624 {
2625         if (p_m_mute)
2626                 return;
2627         PDEBUG(DEBUG_PORT, "turning mute on.\n");
2628         p_m_mute = 1;
2629         set_conf(p_m_conf, 0);
2630 }
2631
2632 void PmISDN::mute_off(void)
2633 {
2634         if (!p_m_mute)
2635                 return;
2636         PDEBUG(DEBUG_PORT, "turning mute off.\n");
2637         p_m_mute = 0;
2638         set_conf(0, p_m_conf);
2639 }
2640
2641