fix and work
[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 #ifndef SOCKET_MISDN
15 // old mISDN
16 extern "C" {
17 #include <mISDNuser/net_l2.h>
18 }
19
20 #ifndef CMX_TXDATA_ON
21 #define OLD_MISDN
22 #endif
23 #ifndef CMX_TXDATA_OFF
24 #define OLD_MISDN
25 #endif
26 #ifndef CMX_DELAY
27 #define OLD_MISDN
28 #endif
29 #ifndef PIPELINE_CFG
30 #define OLD_MISDN
31 #endif
32 #ifndef CMX_TX_DATA
33 #define OLD_MISDN
34 #endif
35
36 #ifdef OLD_MISDN
37 #warning
38 #warning *********************************************************
39 #warning *
40 #warning * It seems that you use an older version of mISDN.
41 #warning * Features like voice recording or echo will not work.
42 #warning * Also it causes problems with loading modules and may
43 #warning * not work at all.
44 #warning *
45 #warning * Please upgrade to newer version. A working version can
46 #warning * be found at www.linux-call-router.de.
47 #warning *
48 #warning * Do not use the mISDN_1_1 branch, it does not have all
49 #warning * the features that are required. Use the master branch
50 #warning * instead.
51 #warning *
52 #warning *********************************************************
53 #warning
54 #error
55 #endif
56
57 #ifndef ISDN_PID_L4_B_USER
58 #define ISDN_PID_L4_B_USER 0x440000ff
59 #endif
60
61 #else
62 // socket mISDN
63 extern "C" {
64 }
65 #include <q931.h>
66
67 #undef offsetof
68 #ifdef __compiler_offsetof
69 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
70 #else
71 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
72 #endif
73
74 #define container_of(ptr, type, member) ({                      \
75         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
76         (type *)( (char *)__mptr - offsetof(type,member) );})
77 #endif
78
79 // timeouts if activating/deactivating response from mISDN got lost
80 #define B_TIMER_ACTIVATING 1 // seconds
81 #define B_TIMER_DEACTIVATING 1 // seconds
82
83 /* list of mISDN ports */
84 struct mISDNport *mISDNport_first;
85
86 /* noise randomizer */
87 unsigned char mISDN_rand[256];
88 int mISDN_rand_count = 0;
89
90 #ifdef SOCKET_MISDN
91 unsigned long mt_assign_pid = ~0;
92
93 int mISDNsocket = -1;
94
95 int mISDN_initialize(void)
96 {
97         char filename[256];
98
99         /* try to open raw socket to check kernel */
100         mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
101         if (mISDNsocket < 0)
102         {
103                 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
104                 return(-1);
105         }
106
107         /* init mlayer3 */
108         init_layer3(4); // buffer of 4
109
110         /* open debug, if enabled and not only stack debugging */
111         if (options.deb)
112         {
113                 SPRINT(filename, "%s/debug.log", INSTALL_DATA);
114                 debug_fp = fopen(filename, "a");
115         }
116
117         if (options.deb & DEBUG_STACK)
118         {
119                 SPRINT(filename, "%s/debug_mISDN.log", INSTALL_DATA);
120                 mISDN_debug_init(0xffffffff, filename, filename, filename);
121         } else
122                 mISDN_debug_init(0, NULL, NULL, NULL);
123
124         return(0);
125 }
126
127 void mISDN_deinitialize(void)
128 {
129         cleanup_layer3();
130
131         mISDN_debug_close();
132
133         if (debug_fp)
134                 fclose(debug_fp);
135         debug_fp = NULL;
136
137         if (mISDNsocket > -1)
138                 close(mISDNsocket);
139 }
140 #else
141 int entity = 0; /* used for udevice */
142 int mISDNdevice = -1; /* the device handler and port list */
143
144 int mISDN_initialize(void)
145 {
146         char debug_log[128];
147         unsigned char buff[1025];
148         iframe_t *frm = (iframe_t *)buff;
149         int ret;
150
151         /* initialize stuff of the NT lib */
152         if (options.deb & DEBUG_STACK)
153         {
154                 global_debug = 0xffffffff & ~DBGM_MSG;
155 //              global_debug = DBGM_L3DATA;
156         } else
157                 global_debug = DBGM_MAN;
158         SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
159         if (options.deb & DEBUG_LOG)
160                 debug_init(global_debug, debug_log, debug_log, debug_log);
161         else
162                 debug_init(global_debug, NULL, NULL, NULL);
163         msg_init();
164
165         /* open mISDNdevice if not already open */
166         if (mISDNdevice < 0)
167         {
168                 ret = mISDN_open();
169                 if (ret < 0)
170                 {
171                         fprintf(stderr, "cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
172                         return(-1);
173                 }
174                 mISDNdevice = ret;
175                 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
176
177                 /* create entity for layer 3 TE-mode */
178                 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
179                 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
180                 if (ret < (int)mISDN_HEADER_LEN)
181                 {
182                         noentity:
183                         FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
184                 }
185                 entity = frm->dinfo & 0xffff;
186                 if (!entity)
187                         goto noentity;
188                 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
189         }
190         return(0);
191 }
192
193 void mISDN_deinitialize(void)
194 {
195         unsigned char buff[1025];
196
197         debug_close();
198         global_debug = 0;
199
200         if (mISDNdevice > -1)
201         {
202                 /* free entity */
203                 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
204                 /* close device */
205                 mISDN_close(mISDNdevice);
206                 mISDNdevice = -1;
207                 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
208         }
209 }
210 #endif
211
212 /*
213  * constructor
214  */
215 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
216 {
217         p_m_mISDNport = mISDNport;
218         p_m_portnum = mISDNport->portnum;
219         p_m_b_index = -1;
220         p_m_b_channel = 0;
221         p_m_b_exclusive = 0;
222         p_m_b_reserve = 0;
223         p_m_delete = 0;
224         p_m_hold = 0;
225         p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
226         p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
227         p_m_conf = 0;
228         p_m_txdata = 0;
229         p_m_delay = 0;
230         p_m_echo = 0;
231         p_m_tone = 0;
232         p_m_rxoff = 0;
233         p_m_joindata = 0;
234         p_m_dtmf = !mISDNport->ifport->nodtmf;
235         p_m_timeout = 0;
236         p_m_timer = 0;
237         p_m_remote_ref = 0; /* channel shall be exported to given remote */
238         p_m_remote_id = 0; /* channel shall be exported to given remote */
239         SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
240         
241         /* audio */
242         p_m_load = 0;
243         p_m_last_tv_sec = 0;
244
245         /* crypt */
246         p_m_crypt = 0;
247         p_m_crypt_listen = 0;
248         p_m_crypt_msg_loops = 0;
249         p_m_crypt_msg_loops = 0;
250         p_m_crypt_msg_len = 0;
251         p_m_crypt_msg[0] = '\0';
252         p_m_crypt_msg_current = 0;
253         p_m_crypt_key_len = 0;
254         p_m_crypt_listen = 0;
255         p_m_crypt_listen_state = 0;
256         p_m_crypt_listen_len = 0;
257         p_m_crypt_listen_msg[0] = '\0';
258         p_m_crypt_listen_crc = 0;
259         if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
260         {
261                 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
262                 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
263                 p_m_crypt = 1;
264         }
265
266         /* if any channel requested by constructor */
267         if (channel == CHANNEL_ANY)
268         {
269                 /* reserve channel */
270                 p_m_b_reserve = 1;
271                 mISDNport->b_reserved++;
272         }
273
274         /* reserve channel */
275         if (channel > 0) // only if constructor was called with a channel resevation
276                 seize_bchannel(channel, exclusive);
277
278         /* we increase the number of objects: */
279         mISDNport->use++;
280         PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
281 }
282
283
284 /*
285  * destructor
286  */
287 PmISDN::~PmISDN()
288 {
289         struct lcr_msg *message;
290
291         /* remove bchannel relation */
292         drop_bchannel();
293
294         /* release epoint */
295         while (p_epointlist)
296         {
297                 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
298                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
299                 message->param.disconnectinfo.cause = 16;
300                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
301                 message_put(message);
302                 /* remove from list */
303                 free_epointlist(p_epointlist);
304         }
305
306         /* we decrease the number of objects: */
307         p_m_mISDNport->use--;
308         PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
309 }
310
311
312 /*
313  * trace
314  */
315 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
316 {
317         /* init trace with given values */
318         start_trace(mISDNport?mISDNport->portnum:0,
319                     (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
320                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
321                     port?port->p_dialinginfo.id:NULL,
322                     direction,
323                     CATEGORY_CH,
324                     port?port->p_serial:0,
325                     msgtext);
326 }
327
328
329 /*
330  * layer trace header
331  */
332 static struct isdn_message {
333         char *name;
334         unsigned long value;
335 } isdn_message[] = {
336         {"PH_ACTIVATE", L1_ACTIVATE_REQ},
337         {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
338         {"DL_ESTABLISH", L2_ESTABLISH_REQ},
339         {"DL_RELEASE", L2_RELEASE_REQ},
340         {"UNKNOWN", L3_UNKNOWN},
341         {"MT_TIMEOUT", L3_TIMEOUT_REQ},
342         {"MT_SETUP", L3_SETUP_REQ},
343         {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
344         {"MT_PROCEEDING", L3_PROCEEDING_REQ},
345         {"MT_ALERTING", L3_ALERTING_REQ},
346         {"MT_CONNECT", L3_CONNECT_REQ},
347         {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
348         {"MT_DISCONNECT", L3_DISCONNECT_REQ},
349         {"MT_RELEASE", L3_RELEASE_REQ},
350         {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
351         {"MT_INFORMATION", L3_INFORMATION_REQ},
352         {"MT_PROGRESS", L3_PROGRESS_REQ},
353         {"MT_NOTIFY", L3_NOTIFY_REQ},
354         {"MT_SUSPEND", L3_SUSPEND_REQ},
355         {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
356         {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
357         {"MT_RESUME", L3_RESUME_REQ},
358         {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
359         {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
360         {"MT_HOLD", L3_HOLD_REQ},
361         {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
362         {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
363         {"MT_RETRIEVE", L3_RETRIEVE_REQ},
364         {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
365         {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
366         {"MT_FACILITY", L3_FACILITY_REQ},
367         {"MT_STATUS", L3_STATUS_REQ},
368         {"MT_RESTART", L3_RESTART_REQ},
369 #ifdef SOCKET_MISDN
370         {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
371         {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
372 #else
373         {"MT_NEW_CR", L3_NEW_CR_REQ},
374         {"MT_RELEASE_CR", L3_RELEASE_CR_REQ},
375 #endif
376
377         {NULL, 0},
378 };
379 static char *isdn_prim[4] = {
380         " REQUEST",
381         " CONFIRM",
382         " INDICATION",
383         " RESPONSE",
384 };
385 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long msg, int direction)
386 {
387         int i;
388         char msgtext[64] = "<<UNKNOWN MESSAGE>>";
389
390         /* select message and primitive text */
391         i = 0;
392         while(isdn_message[i].name)
393         {
394                 if (isdn_message[i].value == (msg&0xffffff00))
395                 {
396                         SCPY(msgtext, isdn_message[i].name);
397                         break;
398                 }
399                 i++;
400         }
401         SCAT(msgtext, isdn_prim[msg&0x00000003]);
402
403         /* add direction */
404 #ifdef SOCKET_MISDN
405         if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
406 #else
407         if (direction && (msg&0xffffff00)!=L3_NEW_CR_REQ && (msg&0xffffff00)!=L3_RELEASE_CR_REQ)
408 #endif
409         {
410                 if (mISDNport)
411                 {
412                         if (mISDNport->ntmode)
413                         {
414                                 if (direction == DIRECTION_OUT)
415                                         SCAT(msgtext, " N->U");
416                                 else
417                                         SCAT(msgtext, " N<-U");
418                         } else
419                         {
420                                 if (direction == DIRECTION_OUT)
421                                         SCAT(msgtext, " U->N");
422                                 else
423                                         SCAT(msgtext, " U<-N");
424                         }
425                 }
426         }
427
428         /* init trace with given values */
429         start_trace(mISDNport?mISDNport->portnum:0,
430                     mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
431                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
432                     port?port->p_dialinginfo.id:NULL,
433                     direction,
434                     CATEGORY_CH,
435                     port?port->p_serial:0,
436                     msgtext);
437 }
438
439
440 /*
441  * send control information to the channel (dsp-module)
442  */
443 #ifdef SOCKET_MISDN
444 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long sock, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
445 {
446         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
447         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
448         unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
449         int ret;
450
451         if (sock < 0)
452                 return;
453
454         ctrl->prim = PH_CONTROL_REQ;
455         ctrl->id = 0;
456         *d++ = c1;
457         *d++ = c2;
458         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
459         if (ret <= 0)
460                 PERROR("Failed to send to socket %d\n", sock);
461 #else
462 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long addr, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
463 {
464         unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
465         iframe_t *ctrl = (iframe_t *)buffer; 
466         unsigned long *d = (unsigned long *)&ctrl->data.p;
467
468         if (!addr)
469                 return;
470
471         ctrl->prim = PH_CONTROL | REQUEST;
472         ctrl->addr = addr | FLG_MSG_DOWN;
473         ctrl->dinfo = 0;
474         ctrl->len = sizeof(int)*2;
475         *d++ = c1;
476         *d++ = c2;
477         mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
478 #endif
479         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
480 #ifdef SOCKET_MISDN
481         if (c1 == DSP_CONF_JOIN)
482 #else
483         if (c1 == CMX_CONF_JOIN)
484 #endif
485                 add_trace(trace_name, NULL, "0x%08x", trace_value);
486         else
487                 add_trace(trace_name, NULL, "%d", trace_value);
488         end_trace();
489 }
490
491 #ifdef SOCKET_MISDN
492 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
493 {
494         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
495         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
496         unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
497         int ret;
498
499         if (sock < 0)
500                 return;
501
502         ctrl->prim = PH_CONTROL_REQ;
503         ctrl->id = 0;
504         *d++ = c1;
505         memcpy(d, c2, c2_len);
506         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
507         if (ret <= 0)
508                 PERROR("Failed to send to socket %d\n", sock);
509 #else
510 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long addr, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
511 {
512         unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
513         iframe_t *ctrl = (iframe_t *)buffer;
514         unsigned long *d = (unsigned long *)&ctrl->data.p;
515
516         if (!addr)
517                 return;
518
519         ctrl->prim = PH_CONTROL | REQUEST;
520         ctrl->addr = addr | FLG_MSG_DOWN;
521         ctrl->dinfo = 0;
522         ctrl->len = sizeof(int)+c2_len;
523         *d++ = c1;
524         memcpy(d, c2, c2_len);
525         mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
526 #endif
527         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
528         add_trace(trace_name, NULL, "%d", trace_value);
529         end_trace();
530 }
531
532
533 /*
534  * subfunction for bchannel_event
535  * create stack
536  */
537 static int _bchannel_create(struct mISDNport *mISDNport, int i)
538 {
539         int ret;
540 #ifdef SOCKET_MISDN
541         unsigned long on = 1;
542         struct sockaddr_mISDN addr;
543
544         if (mISDNport->b_socket[i] > -1)
545         {
546                 PERROR("Error: Socket already created for index %d\n", i);
547                 return(0);
548         }
549
550         /* open socket */
551 //#warning testing without DSP
552 //      mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW);
553         mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
554         if (mISDNport->b_socket[i] < 0)
555         {
556                 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
557                 return(0);
558         }
559         
560         /* set nonblocking io */
561         ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
562         if (ret < 0)
563         {
564                 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
565                 close(mISDNport->b_socket[i]);
566                 mISDNport->b_socket[i] = -1;
567                 return(0);
568         }
569
570         /* bind socket to bchannel */
571         addr.family = AF_ISDN;
572         addr.dev = mISDNport->portnum-1;
573         addr.channel = i+1+(i>=15);
574         ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
575         if (ret < 0)
576         {
577                 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
578                 close(mISDNport->b_socket[i]);
579                 mISDNport->b_socket[i] = -1;
580                 return(0);
581         }
582
583         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
584         add_trace("channel", NULL, "%d", i+1+(i>=15));
585         add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
586         end_trace();
587
588         return(1);
589 #else
590         unsigned char buff[1024];
591         layer_info_t li;
592         mISDN_pid_t pid;
593
594         if (!mISDNport->b_stid[i])
595         {
596                 PERROR("Error: no stack for index %d\n", i);
597                 return(0);
598         }
599         if (mISDNport->b_addr[i])
600         {
601                 PERROR("Error: stack already created for index %d\n", i);
602                 return(0);
603         }
604
605         /* create new layer */
606         PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
607         memset(&li, 0, sizeof(li));
608         memset(&pid, 0, sizeof(pid));
609         li.object_id = -1;
610         li.extentions = 0;
611         li.st = mISDNport->b_stid[i];
612         UCPY(li.name, "B L4");
613         li.pid.layermask = ISDN_LAYER((4));
614         li.pid.protocol[4] = ISDN_PID_L4_B_USER;
615         ret = mISDN_new_layer(mISDNdevice, &li);
616         if (ret)
617         {
618                 failed_new_layer:
619                 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
620                 goto failed;
621         }
622         mISDNport->b_addr[i] = li.id;
623         if (!li.id)
624         {
625                 goto failed_new_layer;
626         }
627         PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
628
629         /* create new stack */
630         pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
631         pid.protocol[2] = ISDN_PID_L2_B_TRANS;
632         pid.protocol[3] = ISDN_PID_L3_B_DSP;
633         pid.protocol[4] = ISDN_PID_L4_B_USER;
634         pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
635         ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
636         if (ret)
637         {
638                 stack_error:
639                 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
640                 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
641                 goto failed;
642         }
643         ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
644         if (ret)
645                 goto stack_error;
646
647         /* get layer id */
648         mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
649         if (!mISDNport->b_addr[i])
650                 goto stack_error;
651         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
652         add_trace("channel", NULL, "%d", i+1+(i>=15));
653         add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
654         add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
655         end_trace();
656
657         return(1);
658
659 failed:
660         mISDNport->b_addr[i] = 0;
661         return(0);
662 #endif
663 }
664
665
666 /*
667  * subfunction for bchannel_event
668  * activate / deactivate request
669  */
670 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
671 {
672 #ifdef SOCKET_MISDN
673         struct mISDNhead act;
674         int ret;
675
676         if (mISDNport->b_socket[i] < 0)
677                 return;
678         act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ; 
679         act.id = 0;
680         ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
681         if (ret <= 0)
682                 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
683 #else
684         iframe_t act;
685
686         /* activate bchannel */
687         act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST; 
688         act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
689         act.dinfo = 0;
690         act.len = 0;
691         mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
692 #endif
693
694         /* trace */
695         chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
696         add_trace("channel", NULL, "%d", i+1+(i>=15));
697         if (mISDNport->b_timer[i])
698                 add_trace("event", NULL, "timeout recovery");
699         end_trace();
700 }
701
702
703 /*
704  * subfunction for bchannel_event
705  * set features
706  */
707 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
708 {
709         struct PmISDN *port;
710 #ifdef SOCKET_MISDN
711         int handle;
712
713         if (mISDNport->b_socket[i] < 0)
714                 return;
715         handle = mISDNport->b_socket[i];
716         port = mISDNport->b_port[i];
717         if (!port)
718         {
719                 PERROR("bchannel index i=%d not associated with a port object\n", i);
720                 return;
721         }
722
723         /* set dsp features */
724         if (port->p_m_txdata)
725                 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
726         if (port->p_m_delay)
727                 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
728         if (port->p_m_tx_gain)
729                 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
730         if (port->p_m_rx_gain)
731                 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
732         if (port->p_m_pipeline[0])
733                 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
734         if (port->p_m_conf)
735                 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
736         if (port->p_m_echo)
737                 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
738         if (port->p_m_tone)
739                 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
740         if (port->p_m_rxoff)
741                 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
742 //      if (port->p_m_txmix)
743 //              ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
744         if (port->p_m_dtmf)
745                 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
746         if (port->p_m_crypt)
747                 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);
748 #else
749         unsigned long handle;
750
751         handle = mISDNport->b_addr[i];
752         port = mISDNport->b_port[i];
753         if (!port)
754         {
755                 PERROR("bchannel index i=%d not associated with a port object\n", i);
756                 return;
757         }
758
759         /* set dsp features */
760 #ifndef OLD_MISDN
761         if (port->p_m_txdata)
762                 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
763         if (port->p_m_delay)
764                 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
765 #endif
766         if (port->p_m_tx_gain)
767                 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
768         if (port->p_m_rx_gain)
769                 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
770 #ifndef OLD_MISDN
771         if (port->p_m_pipeline[0])
772                 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
773 #endif
774         if (port->p_m_conf)
775                 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
776         if (port->p_m_echo)
777                 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
778         if (port->p_m_tone)
779                 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
780         if (port->p_m_rxoff)
781                 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
782 //      if (port->p_m_txmix)
783 //              ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
784         if (port->p_m_dtmf)
785                 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
786         if (port->p_m_crypt)
787                 ph_control_block(mISDNport, port, handle, BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
788 #endif
789 }
790
791 /*
792  * subfunction for bchannel_event
793  * destroy stack
794  */
795 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
796 {
797 #ifdef SOCKET_MISDN
798         if (mISDNport->b_socket[i] < 0)
799                 return;
800         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
801         add_trace("channel", NULL, "%d", i+1+(i>=15));
802         add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
803         end_trace();
804         close(mISDNport->b_socket[i]);
805         mISDNport->b_socket[i] = -1;
806 #else
807         unsigned char buff[1024];
808
809         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
810         add_trace("channel", NULL, "%d", i+1+(i>=15));
811         add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
812         add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
813         end_trace();
814         /* remove our stack only if set */
815         if (mISDNport->b_addr[i])
816         {
817                 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
818                 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
819                 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
820                 mISDNport->b_addr[i] = 0;
821         }
822 #endif
823 }
824
825
826 /*
827 bchannel procedure
828 ------------------
829
830 A bchannel goes through the following states in this order:
831
832 - B_STATE_IDLE
833 No one is using the bchannel.
834 It is available and not linked to Port class, nor reserved.
835
836 - B_STATE_ACTIVATING
837 The bchannel stack is created and an activation request is sent.
838 It MAY be linked to Port class, but already unlinked due to Port class removal.
839
840 - B_STATE_ACTIVE
841 The bchannel is active and cofigured to the Port class needs.
842 Also it is linked to a Port class, otherwhise it would be deactivated.
843
844 - B_STATE_DEACTIVATING
845 The bchannel is in deactivating state, due to deactivation request.
846 It may be linked to a Port class, that likes to reactivate it.
847
848 - B_STATE_IDLE
849 See above.
850 After deactivating bchannel, and if not used, the bchannel becomes idle again.
851
852 Also the bchannel may be exported, but only if the state is or becomes idle:
853
854 - B_STATE_EXPORTING
855 The bchannel assignment has been sent to the remove application.
856
857 - B_STATE_REMOTE
858 The bchannel assignment is acknowledged by the remote application.
859
860 - B_STATE_IMPORTING
861 The bchannel is re-imported by mISDN port object.
862
863 - B_STATE_IDLE
864 See above.
865 After re-importing bchannel, and if not used, the bchannel becomes idle again.
866
867
868 A bchannel can have the following events:
869
870 - B_EVENT_USE
871 A bchannel is required by a Port class.
872 The bchannel shall be exported to the remote application.
873
874 - B_EVENT_ACTIVATED
875 The bchannel beomes active.
876
877 - B_EVENT_DROP
878 The bchannel is not required by Port class anymore
879
880 - B_EVENT_DEACTIVATED
881 The bchannel becomes inactive.
882
883 - B_EVENT_EXPORTED
884 The bchannel is now used by remote application.
885
886 - B_EVENT_IMPORTED
887 The bchannel is not used by remote application.
888
889 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
890
891 if an export request is receive by remote application, p_m_remote_* is set.
892 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.)
893 - set on export request from remote application (if port is assigned)
894 - set on channel use, if requested by remote application (p_m_remote_*)
895 - cleared on drop request
896
897 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
898 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
899 the bchannel import/export is acknowledged with stack given.
900
901 if exporting, b_remote_*[index] is set to the remote socket id.
902 if importing has been acknowledged. b_remote_*[index] is cleared.
903
904 */
905
906 /*
907  * process bchannel events
908  * - mISDNport is a pointer to the port's structure
909  * - i is the index of the bchannel
910  * - event is the B_EVENT_* value
911  * - port is the PmISDN class pointer
912  */
913 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
914 {
915         class PmISDN *b_port = mISDNport->b_port[i];
916         int state = mISDNport->b_state[i];
917         double timer = mISDNport->b_timer[i];
918         unsigned long p_m_remote_ref = 0;
919         unsigned long p_m_remote_id = 0;
920         int p_m_tx_gain = 0;
921         int p_m_rx_gain = 0;
922         char *p_m_pipeline = NULL;
923         unsigned char *p_m_crypt_key = NULL;
924         int p_m_crypt_key_len = 0;
925         int p_m_crypt_key_type = 0;
926 #ifdef SOCKET_MISDN
927         unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
928 #else
929         unsigned long portid = mISDNport->b_stid[i];
930 #endif
931
932         if (b_port)
933         {
934                 p_m_remote_id = b_port->p_m_remote_id;
935                 p_m_remote_ref = b_port->p_m_remote_ref;
936                 p_m_tx_gain = b_port->p_m_tx_gain;
937                 p_m_rx_gain = b_port->p_m_rx_gain;
938                 p_m_pipeline = b_port->p_m_pipeline;
939                 p_m_crypt_key = b_port->p_m_crypt_key;
940                 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
941                 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
942         }
943
944         switch(event)
945         {
946                 case B_EVENT_USE:
947                 /* port must be linked in order to allow activation */
948                 if (!b_port)
949                         FATAL("bchannel must be linked to a Port class\n");
950                 switch(state)
951                 {
952                         case B_STATE_IDLE:
953                         if (p_m_remote_ref)
954                         {
955                                 /* export bchannel */
956                                 message_bchannel_to_join(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);
957                                 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
958                                 add_trace("type", NULL, "assign");
959 #ifdef SOCKET_MISDN
960                                 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
961 #else
962                                 add_trace("socket", "id", "%d", portid);
963 #endif
964                                 end_trace();
965                                 state = B_STATE_EXPORTING;
966                                 mISDNport->b_remote_id[i] = p_m_remote_id;
967                                 mISDNport->b_remote_ref[i] = p_m_remote_ref;
968                         } else
969                         {
970                                 /* create stack and send activation request */
971                                 if (_bchannel_create(mISDNport, i))
972                                 {
973                                         _bchannel_activate(mISDNport, i, 1);
974                                         state = B_STATE_ACTIVATING;
975                                         timer = now_d + B_TIMER_ACTIVATING;
976                                 }
977                         }
978                         break;
979
980                         case B_STATE_ACTIVATING:
981                         case B_STATE_EXPORTING:
982                         /* do nothing, because it is already activating */
983                         break;
984
985                         case B_STATE_DEACTIVATING:
986                         case B_STATE_IMPORTING:
987                         /* do nothing, because we must wait until we can reactivate */
988                         break;
989
990                         default:
991                         /* problems that might ocurr:
992                          * B_EVENT_USE is received when channel already in use.
993                          * bchannel exported, but not freed by other port
994                          */
995                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
996                 }
997                 break;
998
999                 case B_EVENT_EXPORTREQUEST:
1000                 /* special case where the bchannel is requested by remote */
1001                 if (!p_m_remote_ref)
1002                 {
1003                         PERROR("export request without remote channel set, please correct.\n");
1004                         break;
1005                 }
1006                 switch(state)
1007                 {
1008                         case B_STATE_IDLE:
1009                         /* in case, the bchannel is exported right after seize_bchannel */
1010                         /* export bchannel */
1011                         /* p_m_remote_id is set, when this event happens. */
1012                         message_bchannel_to_join(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);
1013                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1014                         add_trace("type", NULL, "assign");
1015 #ifdef SOCKET_MISDN
1016                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1017 #else
1018                         add_trace("socket", "id", "%d", portid);
1019 #endif
1020                         end_trace();
1021                         state = B_STATE_EXPORTING;
1022                         mISDNport->b_remote_id[i] = p_m_remote_id;
1023                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
1024                         break;
1025
1026                         case B_STATE_ACTIVATING:
1027                         case B_STATE_EXPORTING:
1028                         /* do nothing, because it is already activating */
1029                         break;
1030
1031                         case B_STATE_DEACTIVATING:
1032                         case B_STATE_IMPORTING:
1033                         /* do nothing, because we must wait until we can reactivate */
1034                         break;
1035
1036                         case B_STATE_ACTIVE:
1037                         /* bchannel is active, so we deactivate */
1038                         _bchannel_activate(mISDNport, i, 0);
1039                         state = B_STATE_DEACTIVATING;
1040                         timer = now_d + B_TIMER_DEACTIVATING;
1041                         break;
1042
1043                         default:
1044                         /* problems that might ocurr:
1045                          * ... when channel already in use.
1046                          * bchannel exported, but not freed by other port
1047                          */
1048                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1049                 }
1050                 break;
1051
1052                 case B_EVENT_ACTIVATED:
1053                 timer = 0;
1054                 switch(state)
1055                 {
1056                         case B_STATE_ACTIVATING:
1057                         if (b_port && !p_m_remote_id)
1058                         {
1059                                 /* bchannel is active and used by Port class, so we configure bchannel */
1060                                 _bchannel_configure(mISDNport, i);
1061                                 state = B_STATE_ACTIVE;
1062                         } else
1063                         {
1064                                 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
1065                                 _bchannel_activate(mISDNport, i, 0);
1066                                 state = B_STATE_DEACTIVATING;
1067                                 timer = now_d + B_TIMER_DEACTIVATING;
1068                         }
1069                         break;
1070
1071                         default:
1072                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1073                 }
1074                 break;
1075
1076                 case B_EVENT_EXPORTED:
1077                 switch(state)
1078                 {
1079                         case B_STATE_EXPORTING:
1080                         if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
1081                         {
1082                                 /* remote export done */
1083                                 state = B_STATE_REMOTE;
1084                         } else
1085                         {
1086                                 /* bchannel is now exported, but we need bchannel back
1087                                  * OR bchannel is not used anymore
1088                                  * OR bchannel has been exported to an obsolete ref,
1089                                  * so reimport, to later export to new remote */
1090                                 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1091                                 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1092                                 add_trace("type", NULL, "remove");
1093 #ifdef SOCKET_MISDN
1094                                 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1095 #else
1096                                 add_trace("socket", "id", "%d", portid);
1097 #endif
1098                                 end_trace();
1099                                 state = B_STATE_IMPORTING;
1100                         }
1101                         break;
1102
1103                         default:
1104                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1105                 }
1106                 break;
1107
1108                 case B_EVENT_DROP:
1109                 if (!b_port)
1110                         FATAL("bchannel must be linked to a Port class\n");
1111                 switch(state)
1112                 {
1113                         case B_STATE_IDLE:
1114                         /* bchannel is idle due to an error, so we do nothing */
1115                         break;
1116
1117                         case B_STATE_ACTIVATING:
1118                         case B_STATE_EXPORTING:
1119                         /* do nothing because we must wait until bchanenl is active before deactivating */
1120                         break;
1121
1122                         case B_STATE_ACTIVE:
1123                         /* bchannel is active, so we deactivate */
1124                         _bchannel_activate(mISDNport, i, 0);
1125                         state = B_STATE_DEACTIVATING;
1126                         timer = now_d + B_TIMER_DEACTIVATING;
1127                         break;
1128
1129                         case B_STATE_REMOTE:
1130                         /* bchannel is exported, so we re-import */
1131                         message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1132                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1133                         add_trace("type", NULL, "remove");
1134 #ifdef SOCKET_MISDN
1135                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1136 #else
1137                         add_trace("socket", "id", "%d", portid);
1138 #endif
1139                         end_trace();
1140                         state = B_STATE_IMPORTING;
1141                         break;
1142
1143                         case B_STATE_DEACTIVATING:
1144                         case B_STATE_IMPORTING:
1145                         /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1146                         break;
1147
1148                         default:
1149                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1150                 }
1151                 break;
1152
1153                 case B_EVENT_DEACTIVATED:
1154                 timer = 0;
1155                 switch(state)
1156                 {
1157                         case B_STATE_IDLE:
1158                         /* ignore due to deactivation confirm after unloading */
1159                         break;
1160
1161                         case B_STATE_DEACTIVATING:
1162                         _bchannel_destroy(mISDNport, i);
1163                         state = B_STATE_IDLE;
1164                         if (b_port)
1165                         {
1166                                 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1167                                 if (p_m_remote_ref)
1168                                 {
1169                                         message_bchannel_to_join(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);
1170                                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1171                                         add_trace("type", NULL, "assign");
1172 #ifdef SOCKET_MISDN
1173                                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1174 #else
1175                                         add_trace("socket", "id", "%d", portid);
1176 #endif
1177                                         end_trace();
1178                                         state = B_STATE_EXPORTING;
1179                                         mISDNport->b_remote_id[i] = p_m_remote_id;
1180                                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
1181                                 } else
1182                                 {
1183                                         if (_bchannel_create(mISDNport, i))
1184                                         {
1185                                                 _bchannel_activate(mISDNport, i, 1);
1186                                                 state = B_STATE_ACTIVATING;
1187                                                 timer = now_d + B_TIMER_ACTIVATING;
1188                                         }
1189                                 }
1190                         }
1191                         break;
1192
1193                         default:
1194                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1195                 }
1196                 break;
1197
1198                 case B_EVENT_IMPORTED:
1199                 switch(state)
1200                 {
1201                         case B_STATE_IMPORTING:
1202                         state = B_STATE_IDLE;
1203                         mISDNport->b_remote_id[i] = 0;
1204                         mISDNport->b_remote_ref[i] = 0;
1205                         if (b_port)
1206                         {
1207                                 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1208                                 if (p_m_remote_ref)
1209                                 {
1210                                         message_bchannel_to_join(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);
1211                                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1212                                         add_trace("type", NULL, "assign");
1213 #ifdef SOCKET_MISDN
1214                                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1215 #else
1216                                         add_trace("socket", "id", "%d", portid);
1217 #endif
1218                                         end_trace();
1219                                         state = B_STATE_EXPORTING;
1220                                         mISDNport->b_remote_id[i] = p_m_remote_id;
1221                                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
1222                                 } else
1223                                 {
1224                                         if (_bchannel_create(mISDNport, i))
1225                                         {
1226                                                 _bchannel_activate(mISDNport, i, 1);
1227                                                 state = B_STATE_ACTIVATING;
1228                                                 timer = now_d + B_TIMER_ACTIVATING;
1229                                         }
1230                                 }
1231                         }
1232                         break;
1233
1234                         default:
1235                         /* ignore, because not assigned */
1236                         ;
1237                 }
1238                 break;
1239
1240                 case B_EVENT_TIMEOUT:
1241                 timer = 0;
1242                 switch(state)
1243                 {
1244                         case B_STATE_IDLE:
1245                         /* ignore due to deactivation confirm after unloading */
1246                         break;
1247
1248                         case B_STATE_ACTIVATING:
1249                         _bchannel_activate(mISDNport, i, 1);
1250                         timer = now_d + B_TIMER_ACTIVATING;
1251                         break;
1252
1253                         case B_STATE_DEACTIVATING:
1254                         _bchannel_activate(mISDNport, i, 0);
1255                         timer = now_d + B_TIMER_DEACTIVATING;
1256                         break;
1257
1258                         default:
1259                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1260                 }
1261                 break;
1262
1263                 default:
1264                 PERROR("Illegal event %d, please correct.\n", event);
1265         }
1266
1267         mISDNport->b_state[i] = state;
1268         mISDNport->b_timer[i] = timer;
1269 }
1270
1271
1272
1273
1274 /*
1275  * check for available channel and reserve+set it.
1276  * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1277  * give exclusiv flag
1278  * returns -(cause value) or x = channel x or 0 = no channel
1279  * NOTE: no activation is done here
1280  */
1281 int PmISDN::seize_bchannel(int channel, int exclusive)
1282 {
1283         int i;
1284
1285         /* the channel is what we have */
1286         if (p_m_b_channel == channel)
1287                 return(channel);
1288
1289         /* if channel already in use, release it */
1290         if (p_m_b_channel)
1291                 drop_bchannel();
1292
1293         /* if CHANNEL_NO */
1294         if (channel==CHANNEL_NO || channel==0)
1295                 return(0);
1296         
1297         /* is channel in range ? */
1298         if (channel==16
1299          || (channel>p_m_mISDNport->b_num && channel<16)
1300          || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1301                 return(-6); /* channel unacceptable */
1302
1303         /* request exclusive channel */
1304         if (exclusive && channel>0)
1305         {
1306                 i = channel-1-(channel>16);
1307                 if (p_m_mISDNport->b_port[i])
1308                         return(-44); /* requested channel not available */
1309                 goto seize;
1310         }
1311
1312         /* ask for channel */
1313         if (channel>0)
1314         {
1315                 i = channel-1-(channel>16);
1316                 if (p_m_mISDNport->b_port[i] == NULL)
1317                         goto seize;
1318         }
1319
1320         /* search for channel */
1321         i = 0;
1322         while(i < p_m_mISDNport->b_num)
1323         {
1324                 if (!p_m_mISDNport->b_port[i])
1325                 {
1326                         channel = i+1+(i>=15);
1327                         goto seize;
1328                 }
1329                 i++;
1330         }
1331         return(-34); /* no free channel */
1332
1333 seize:
1334         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1335
1336         /* link Port */
1337         p_m_mISDNport->b_port[i] = this;
1338         p_m_b_index = i;
1339         p_m_b_channel = channel;
1340         p_m_b_exclusive = exclusive;
1341
1342         /* reserve channel */
1343         if (!p_m_b_reserve)
1344         {
1345                 p_m_b_reserve = 1;
1346                 p_m_mISDNport->b_reserved++;
1347         }
1348
1349         return(channel);
1350 }
1351
1352 /*
1353  * drop reserved channel and unset it.
1354  * deactivation is also done
1355  */
1356 void PmISDN::drop_bchannel(void)
1357 {
1358         /* unreserve channel */
1359         if (p_m_b_reserve)
1360                 p_m_mISDNport->b_reserved--;
1361         p_m_b_reserve = 0;
1362
1363         /* if not in use */
1364         if (p_m_b_index < 0)
1365                 return;
1366         if (!p_m_b_channel)
1367                 return;
1368
1369         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1370
1371         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1372                 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1373         p_m_mISDNport->b_port[p_m_b_index] = NULL;
1374         p_m_b_index = -1;
1375         p_m_b_channel = 0;
1376         p_m_b_exclusive = 0;
1377 }
1378
1379 /* process bchannel export/import message from join */
1380 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1381 {
1382         class Endpoint *epoint;
1383         class Port *port;
1384         class PmISDN *isdnport;
1385         struct mISDNport *mISDNport;
1386         int i, ii;
1387
1388         switch(type)
1389         {
1390                 case BCHANNEL_REQUEST:
1391                 /* find the port object for the join object ref */
1392                 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1393                 {
1394                         PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1395                         return;
1396                 }
1397                 if (!epoint->ep_portlist)
1398                 {
1399                         PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1400                         return;
1401                 }
1402                 if (epoint->ep_portlist->next)
1403                 {
1404                         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);
1405                 }
1406                 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1407                 {
1408                         PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1409                         return;
1410                 }
1411                 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1412                 {
1413                         PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1414                 }
1415                 isdnport = (class PmISDN *)port;
1416
1417                 /* assign */
1418                 if (isdnport->p_m_remote_id)
1419                 {
1420                         PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1421                         break;
1422                 }
1423                 mISDNport = isdnport->p_m_mISDNport;
1424                 i = isdnport->p_m_b_index;
1425                 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1426                 add_trace("type", NULL, "export request");
1427                 isdnport->p_m_remote_ref = joinremote->j_serial;
1428                 isdnport->p_m_remote_id = joinremote->j_remote_id;
1429                 if (mISDNport && i>=0)
1430                 {
1431                         bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1432                 }
1433                 end_trace();
1434                 break;
1435
1436                 case BCHANNEL_ASSIGN_ACK:
1437                 case BCHANNEL_REMOVE_ACK:
1438                 /* find mISDNport for stack ID */
1439                 mISDNport = mISDNport_first;
1440                 while(mISDNport)
1441                 {
1442                         i = 0;
1443                         ii = mISDNport->b_num;
1444                         while(i < ii)
1445                         {
1446 #ifdef SOCKET_MISDN
1447                                 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1448 #else
1449                                 if (mISDNport->b_addr[i] == handle)
1450 #endif
1451                                         break;
1452                                 i++;
1453                         }
1454                         if (i != ii)
1455                                 break;
1456                         mISDNport = mISDNport->next;
1457                 }
1458                 if (!mISDNport)
1459                 {
1460                         PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1461                         break;
1462                 }
1463                 /* mISDNport may now be set or NULL */
1464                 
1465                 /* set */
1466                 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1467                 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1468                 if (mISDNport && i>=0)
1469                         bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1470                 end_trace();
1471                 break;
1472                 default:
1473                 PERROR("received wrong bchannel message type %d from remote\n", type);
1474         }
1475 }
1476
1477
1478 /*
1479  * handler
1480
1481 audio transmission procedure:
1482 -----------------------------
1483
1484 * priority
1485 three sources of audio transmission:
1486 - crypto-data high priority
1487 - tones high priority (also high)
1488 - remote-data low priority
1489
1490 * elapsed
1491 a variable that temporarily shows the number of samples elapsed since last transmission process.
1492 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1493
1494 * load
1495 a variable that is increased whenever data is transmitted.
1496 it is decreased while time elapses. it stores the number of samples that
1497 are currently loaded to dsp module.
1498 since clock in dsp module is the same clock for user space process, these 
1499 times have no skew.
1500
1501 * levels
1502 there are two levels:
1503 ISDN_LOAD will give the load that have to be kept in dsp.
1504 ISDN_MAXLOAD will give the maximum load before dropping.
1505
1506 * procedure for low priority data
1507 see txfromup() for procedure
1508 in short: remote data is ignored during high priority tones
1509
1510 * procedure for high priority data
1511 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1512 if no more data is available, load becomes empty again.
1513
1514 'load' variable:
1515 0                    ISDN_LOAD           ISDN_MAXLOAD
1516 +--------------------+----------------------+
1517 |                    |                      |
1518 +--------------------+----------------------+
1519
1520 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1521 0                    ISDN_LOAD           ISDN_MAXLOAD
1522 +--------------------+----------------------+
1523 |TTTTTTTTTTTTTTTTTTTT|                      |
1524 +--------------------+----------------------+
1525
1526 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1527 0                    ISDN_LOAD           ISDN_MAXLOAD
1528 +--------------------+----------------------+
1529 |TTTTTTTTTTTTTTTTTTTTRRRRR                  |
1530 +--------------------+----------------------+
1531
1532  */
1533 int PmISDN::handler(void)
1534 {
1535         struct lcr_msg *message;
1536         int elapsed = 0;
1537         int ret;
1538
1539         if ((ret = Port::handler()))
1540                 return(ret);
1541
1542         /* get elapsed */
1543         if (p_m_last_tv_sec)
1544         {
1545                 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1546                         + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1547         } else
1548         {
1549                 /* set clock of first process ever in this instance */
1550                 p_m_last_tv_sec = now_tv.tv_sec;
1551                 p_m_last_tv_msec = now_tv.tv_usec/1000;
1552         }
1553         /* process only if we have a minimum of samples, to make packets not too small */
1554         if (elapsed >= ISDN_TRANSMIT)
1555         {
1556                 /* set clock of last process! */
1557                 p_m_last_tv_sec = now_tv.tv_sec;
1558                 p_m_last_tv_msec = now_tv.tv_usec/1000;
1559
1560                 /* update load */
1561                 if (elapsed < p_m_load)
1562                         p_m_load -= elapsed;
1563                 else
1564                         p_m_load = 0;
1565
1566                 /* to send data, tone must be active OR crypt messages must be on */
1567                 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1568                  && (p_m_load < ISDN_LOAD)
1569                  && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1570                 {
1571                         int tosend = ISDN_LOAD - p_m_load, length; 
1572 #ifdef SOCKET_MISDN
1573                         unsigned char buf[MISDN_HEADER_LEN+tosend];
1574                         struct mISDNhead *frm = (struct mISDNhead *)buf;
1575                         unsigned char *p = buf+MISDN_HEADER_LEN;
1576 #else
1577                         unsigned char buf[mISDN_HEADER_LEN+tosend];
1578                         iframe_t *frm = (iframe_t *)buf;
1579                         unsigned char *p = buf+mISDN_HEADER_LEN;
1580 #endif
1581
1582                         /* copy crypto loops */
1583                         while (p_m_crypt_msg_loops && tosend)
1584                         {
1585                                 /* how much do we have to send */
1586                                 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1587
1588                                 /* clip tosend */
1589                                 if (length > tosend)
1590                                         length = tosend;
1591
1592                                 /* copy message (part) to buffer */
1593                                 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1594
1595                                 /* new position */
1596                                 p_m_crypt_msg_current += length;
1597                                 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1598                                 {
1599                                         /* next loop */
1600                                         p_m_crypt_msg_current = 0;
1601                                         p_m_crypt_msg_loops--;
1602 //                                      puts("eine loop weniger");
1603                                 }
1604
1605                                 /* new length */
1606                                 tosend -= length;
1607                         }
1608
1609                         /* copy tones */
1610                         if (p_tone_name[0] && tosend)
1611                         {
1612                                 tosend -= read_audio(p, tosend);
1613                         }
1614
1615                         /* send data */
1616                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && ISDN_LOAD-p_m_load-tosend > 0)
1617                         {
1618 #ifdef SOCKET_MISDN
1619                                 frm->prim = PH_DATA_REQ;
1620                                 frm->id = 0;
1621                                 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1622                                 if (ret <= 0)
1623                                         PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_socket[p_m_b_index], ISDN_LOAD-p_m_load-tosend);
1624 #else
1625                                 frm->prim = DL_DATA | REQUEST; 
1626                                 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1627                                 frm->dinfo = 0;
1628                                 frm->len = ISDN_LOAD - p_m_load - tosend;
1629                                 if (frm->len)
1630                                         mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1631 #endif
1632                         }
1633                         p_m_load += ISDN_LOAD - p_m_load - tosend;
1634                 }
1635         }
1636
1637         // NOTE: deletion is done by the child class
1638
1639         /* handle timeouts */
1640         if (p_m_timeout)
1641         {
1642                 if (p_m_timer+p_m_timeout < now_d)
1643                 {
1644                         PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1645                         p_m_timeout = 0;
1646                         /* send timeout to endpoint */
1647                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1648                         message->param.state = p_state;
1649                         message_put(message);
1650                         return(1);
1651                 }
1652         }
1653         
1654         return(0); /* nothing done */
1655 }
1656
1657
1658 /*
1659  * whenever we get audio data from bchannel, we process it here
1660  */
1661 #ifdef SOCKET_MISDN
1662 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1663 {
1664         unsigned long cont = *((unsigned long *)data);
1665 #else
1666 void PmISDN::bchannel_receive(iframe_t *frm)
1667 {
1668         int len = frm->len;
1669         unsigned long cont = *((unsigned long *)&frm->data.p);
1670         unsigned char *data =(unsigned char *)&frm->data.p;
1671 #endif
1672         unsigned char *data_temp;
1673         unsigned long length_temp;
1674         struct lcr_msg *message;
1675         unsigned char *p;
1676         int l;
1677
1678 #ifdef SOCKET_MISDN
1679         if (hh->prim == PH_CONTROL_IND)
1680 #else
1681         if (frm->prim == (PH_CONTROL | INDICATION))
1682 #endif
1683         {
1684                 if (len < 4)
1685                 {
1686                         PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1687                         return;
1688                 }
1689                 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1690                 {
1691                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1692                         add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1693                         end_trace();
1694                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1695                         message->param.dtmf = cont & DTMF_TONE_MASK;
1696                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  DTMF digit '%c'\n", p_name, message->param.dtmf);
1697                         message_put(message);
1698                         return;
1699                 }
1700                 switch(cont)
1701                 {
1702 #ifdef SOCKET_MISDN
1703                         case DSP_BF_REJECT:
1704 #else
1705                         case BF_REJECT:
1706 #endif
1707                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1708                         add_trace("DSP-CRYPT", NULL, "error");
1709                         end_trace();
1710                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1711                         message->param.crypt.type = CC_ERROR_IND;
1712                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  reject of blowfish.\n", p_name);
1713                         message_put(message);
1714                         break;
1715
1716 #ifdef SOCKET_MISDN
1717                         case DSP_BF_ACCEPT:
1718 #else
1719                         case BF_ACCEPT:
1720 #endif
1721                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1722                         add_trace("DSP-CRYPT", NULL, "ok");
1723                         end_trace();
1724                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1725                         message->param.crypt.type = CC_ACTBF_CONF;
1726                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  accept of blowfish.\n", p_name);
1727                         message_put(message);
1728                         break;
1729
1730                         default:
1731                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1732                         add_trace("unknown", NULL, "0x%x", cont);
1733                         end_trace();
1734                 }
1735                 return;
1736         }
1737 #ifdef SOCKET_MISDN
1738         if (hh->prim == PH_CONTROL_IND)
1739         {
1740                 switch(hh->id)
1741 #else
1742         if (frm->prim == (PH_SIGNAL | INDICATION)
1743          || frm->prim == (PH_CONTROL | INDICATION))
1744         {
1745                 switch(frm->dinfo)
1746 #endif
1747                 {
1748 #ifndef OLD_MISDN
1749 #ifndef SOCKET_MISDN
1750                         case CMX_TX_DATA:
1751                         if (!p_m_txdata)
1752                         {
1753                                 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1754                                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1755                                 return;
1756                         }
1757                         /* see below (same condition) */
1758                         if (p_state!=PORT_STATE_CONNECT
1759                                  && !p_m_mISDNport->tones)
1760                                 break;
1761 //                      printf(".");fflush(stdout);return;
1762                         if (p_record)
1763                                 record(data, len, 1); // from up
1764                         break;
1765 #endif
1766 #endif
1767
1768                         default:
1769                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1770 #ifdef SOCKET_MISDN
1771                         add_trace("unknown", NULL, "0x%x", hh->id);
1772 #else
1773                         add_trace("unknown", NULL, "0x%x", frm->dinfo);
1774 #endif
1775                         end_trace();
1776                 }
1777                 return;
1778         }
1779 #ifdef SOCKET_MISDN
1780         if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1781         {
1782                 if (!p_m_txdata)
1783                 {
1784                         /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1785                         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1786                         return;
1787                 }
1788                 /* see below (same condition) */
1789                 if (p_state!=PORT_STATE_CONNECT
1790                          && !p_m_mISDNport->tones)
1791                         return;
1792 //              printf(".");fflush(stdout);return;
1793                 if (p_record)
1794                         record(data, len, 1); // from up
1795                 return;
1796         }
1797         if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1798         {
1799                 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1800 #else
1801         if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1802         {
1803                 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1804 #endif
1805                 return;
1806         }
1807         /* calls will not process any audio data unless
1808          * the call is connected OR interface features audio during call setup.
1809          */
1810 //printf("%d -> %d prim=%x joindata=%d tones=%d\n", p_serial, ACTIVE_EPOINT(p_epointlist), frm->prim, p_m_joindata, p_m_mISDNport->earlyb);     
1811 #ifndef DEBUG_COREBRIDGE
1812         if (p_state!=PORT_STATE_CONNECT
1813          && !p_m_mISDNport->tones)
1814                 return;
1815 #endif
1816
1817         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1818         if (p_m_rxoff)
1819         {
1820                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1821                 return;
1822         }
1823
1824         /* record data */
1825         if (p_record)
1826                 record(data, len, 0); // from down
1827
1828         /* randomize and listen to crypt message if enabled */
1829         if (p_m_crypt_listen)
1830         {
1831                 /* the noisy randomizer */
1832                 p = data;
1833                 l = len;
1834                 while(l--)
1835                         mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1836
1837                 cryptman_listen_bch(data, len);
1838         }
1839
1840         p = data;
1841
1842         /* send data to epoint */
1843         if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1844         {
1845                 length_temp = len;
1846                 data_temp = p;
1847                 while(length_temp)
1848                 {
1849                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1850                         message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1851                         memcpy(message->param.data.data, data_temp, message->param.data.len);
1852                         message_put(message);
1853                         if (length_temp <= sizeof(message->param.data.data))
1854                                 break;
1855                         data_temp += sizeof(message->param.data.data);
1856                         length_temp -= sizeof(message->param.data.data);
1857                 }
1858         }
1859 }
1860
1861
1862 /*
1863  * set echotest
1864  */
1865 void PmISDN::set_echotest(int echo)
1866 {
1867         if (p_m_echo != echo)
1868         {
1869                 p_m_echo = echo;
1870                 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1871                 if (p_m_b_channel)
1872                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1873 #ifdef SOCKET_MISDN
1874                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1875 #else
1876                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1877 #endif
1878         }
1879 }
1880
1881 /*
1882  * set tone
1883  */
1884 void PmISDN::set_tone(char *dir, char *tone)
1885 {
1886         int id;
1887
1888         if (!tone)
1889                 tone = "";
1890         PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1891         if (!tone[0])
1892         {
1893                 id = TONE_OFF;
1894                 goto setdsp;
1895         }
1896
1897         /* check if we NOT really have to use a dsp-tone */
1898         if (!options.dsptones)
1899         {
1900                 nodsp:
1901                 if (p_m_tone)
1902                 if (p_m_b_index > -1)
1903                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1904                 {
1905                         PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1906 #ifdef SOCKET_MISDN
1907                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1908 #else
1909                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1910 #endif
1911                 }
1912                 p_m_tone = 0;
1913                 Port::set_tone(dir, tone);
1914                 return;
1915         }
1916         if (p_tone_dir[0])
1917                 goto nodsp;
1918
1919         /* now we USE dsp-tone, convert name */
1920         else if (!strcmp(tone, "dialtone"))
1921         {
1922                 switch(options.dsptones) {
1923                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1924                 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1925                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1926                 }
1927         } else if (!strcmp(tone, "dialpbx"))
1928         {
1929                 switch(options.dsptones) {
1930                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1931                 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1932                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1933                 }
1934         } else if (!strcmp(tone, "ringing"))
1935         {
1936                 switch(options.dsptones) {
1937                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1938                 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1939                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1940                 }
1941         } else if (!strcmp(tone, "ringpbx"))
1942         {
1943                 switch(options.dsptones) {
1944                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1945                 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1946                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1947                 }
1948         } else if (!strcmp(tone, "busy"))
1949         {
1950                 busy:
1951                 switch(options.dsptones) {
1952                 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1953                 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1954                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1955                 }
1956         } else if (!strcmp(tone, "release"))
1957         {
1958                 hangup:
1959                 switch(options.dsptones) {
1960                 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1961                 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1962                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1963                 }
1964         } else if (!strcmp(tone, "cause_10"))
1965                 goto hangup;
1966         else if (!strcmp(tone, "cause_11"))
1967                 goto busy;
1968         else if (!strcmp(tone, "cause_22"))
1969         {
1970                 switch(options.dsptones) {
1971                 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1972                 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1973                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1974                 }
1975         } else if (!strncmp(tone, "cause_", 6))
1976                 id = TONE_SPECIAL_INFO;
1977         else
1978                 id = TONE_OFF;
1979
1980         /* if we have a tone that is not supported by dsp */
1981         if (id==TONE_OFF && tone[0])
1982                 goto nodsp;
1983
1984         setdsp:
1985         if (p_m_tone != id)
1986         {
1987                 /* set new tone */
1988                 p_m_tone = id;
1989                 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1990                 if (p_m_b_index > -1)
1991                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1992 #ifdef SOCKET_MISDN
1993                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1994 #else
1995                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1996 #endif
1997         }
1998         /* turn user-space tones off in cases of no tone OR dsp tone */
1999         Port::set_tone("",NULL);
2000 }
2001
2002
2003 /* MESSAGE_mISDNSIGNAL */
2004 //extern struct lcr_msg *dddebug;
2005 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
2006 {
2007         switch(param->mISDNsignal.message)
2008         {
2009                 case mISDNSIGNAL_VOLUME:
2010                 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
2011                 {
2012                         p_m_tx_gain = param->mISDNsignal.tx_gain;
2013                         PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
2014                         if (p_m_b_index > -1)
2015                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2016 #ifdef SOCKET_MISDN
2017                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
2018 #else
2019                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
2020 #endif
2021                 } else
2022                         PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
2023                 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
2024                 {
2025                         p_m_rx_gain = param->mISDNsignal.rx_gain;
2026                         PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
2027                         if (p_m_b_index > -1)
2028                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2029 #ifdef SOCKET_MISDN
2030                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
2031 #else
2032                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
2033 #endif
2034                 } else
2035                         PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
2036                 break;
2037
2038                 case mISDNSIGNAL_CONF:
2039 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2040 //tone          if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
2041                 if (p_m_conf != param->mISDNsignal.conf)
2042                 {
2043                         p_m_conf = param->mISDNsignal.conf;
2044                         PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
2045                         if (p_m_b_index > -1)
2046                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2047 #ifdef SOCKET_MISDN
2048                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (p_m_conf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
2049 #else
2050                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
2051 #endif
2052                 } else
2053                         PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
2054                 /* we must set, even if currently tone forbids conf */
2055                 p_m_conf = param->mISDNsignal.conf;
2056 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2057                 break;
2058
2059                 case mISDNSIGNAL_JOINDATA:
2060                 if (p_m_joindata != param->mISDNsignal.joindata)
2061                 {
2062                         p_m_joindata = param->mISDNsignal.joindata;
2063                         PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
2064                 } else
2065                         PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
2066                 break;
2067                 
2068                 case mISDNSIGNAL_DELAY:
2069                 if (p_m_delay != param->mISDNsignal.delay)
2070                 {
2071                         p_m_delay = param->mISDNsignal.delay;
2072                         PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
2073 #ifndef OLD_MISDN
2074                         if (p_m_b_index > -1)
2075                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2076 #ifdef SOCKET_MISDN
2077                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
2078 #else
2079                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
2080 #endif
2081 #endif
2082                 } else
2083                         PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
2084                 break;
2085
2086                 default:
2087                 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
2088         }
2089 }
2090
2091 /* MESSAGE_CRYPT */
2092 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
2093 {
2094         struct lcr_msg *message;
2095
2096         switch(param->crypt.type)
2097         {
2098                 case CC_ACTBF_REQ:           /* activate blowfish */
2099                 p_m_crypt = 1;
2100                 p_m_crypt_key_len = param->crypt.len;
2101                 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
2102                 {
2103                         PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
2104                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
2105                         message->param.crypt.type = CC_ERROR_IND;
2106                         message_put(message);
2107                         break;
2108                 }
2109                 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
2110                 crypt_off:
2111                 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
2112                 if (p_m_b_index > -1)
2113                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2114 #ifdef SOCKET_MISDN
2115                         ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], 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);
2116 #else
2117                         ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
2118 #endif
2119                 break;
2120
2121                 case CC_DACT_REQ:            /* deactivate session encryption */
2122                 p_m_crypt = 0;
2123                 goto crypt_off;
2124                 break;
2125
2126                 case CR_LISTEN_REQ:          /* start listening to messages */
2127                 p_m_crypt_listen = 1;
2128                 p_m_crypt_listen_state = 0;
2129                 break;
2130
2131                 case CR_UNLISTEN_REQ:        /* stop listening to messages */
2132                 p_m_crypt_listen = 0;
2133                 break;
2134
2135                 case CR_MESSAGE_REQ:         /* send message */
2136                 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2137                 if (!p_m_crypt_msg_len)
2138                 {
2139                         PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2140                         break;
2141                 }
2142                 p_m_crypt_msg_current = 0; /* reset */
2143                 p_m_crypt_msg_loops = 6; /* enable */
2144 #if 0
2145                 /* disable txmix, or we get corrupt data due to audio process */
2146                 if (p_m_txmix && p_m_b_index>=0)
2147                 {
2148                         PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2149 #ifdef SOCKET_MISDN
2150                         ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
2151 #else
2152                         ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2153 #endif
2154                 }
2155 #endif
2156                 break;
2157
2158                 default:
2159                 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2160         }
2161
2162 }
2163
2164 /*
2165  * endpoint sends messages to the port
2166  */
2167 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2168 {
2169         if (Port::message_epoint(epoint_id, message_id, param))
2170                 return(1);
2171
2172         switch(message_id)
2173         {
2174                 case MESSAGE_DATA: /* tx-data from upper layer */
2175                 txfromup(param->data.data, param->data.len);
2176                 return(1);
2177
2178                 case MESSAGE_mISDNSIGNAL: /* user command */
2179                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2180                 message_mISDNsignal(epoint_id, message_id, param);
2181                 return(1);
2182
2183                 case MESSAGE_CRYPT: /* crypt control command */
2184                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2185                 message_crypt(epoint_id, message_id, param);
2186                 return(1);
2187         }
2188
2189         return(0);
2190 }
2191
2192
2193 /*
2194  * main loop for processing messages from mISDN
2195  */
2196 #ifdef SOCKET_MISDN
2197 int mISDN_handler(void)
2198 {
2199         int ret, work = 0;
2200         struct mISDNport *mISDNport;
2201         class PmISDN *isdnport;
2202         int i;
2203         unsigned char buffer[2048+MISDN_HEADER_LEN];
2204         struct mISDNhead *hh = (struct mISDNhead *)buffer;
2205         struct mbuffer *mb;
2206         struct l3_msg *l3m;
2207
2208         /* process all ports */
2209         mISDNport = mISDNport_first;
2210         while(mISDNport)
2211         {
2212                 /* process all bchannels */
2213                 i = 0;
2214                 while(i < mISDNport->b_num)
2215                 {
2216                         /* process timer events for bchannel handling */
2217                         if (mISDNport->b_timer[i])
2218                         {
2219                                 if (mISDNport->b_timer[i] <= now_d)
2220                                         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2221                         }
2222                         /* handle port of bchannel */
2223                         isdnport=mISDNport->b_port[i];
2224                         if (isdnport)
2225                         {
2226                                 /* call bridges in user space OR crypto OR recording */
2227                                 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2228                                 {
2229                                         /* rx IS required */
2230                                         if (isdnport->p_m_rxoff)
2231                                         {
2232                                                 /* turn on RX */
2233                                                 isdnport->p_m_rxoff = 0;
2234                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
2235                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2236                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2237                                                 return(1);
2238                                         }
2239                                 } else
2240                                 {
2241                                         /* rx NOT required */
2242                                         if (!isdnport->p_m_rxoff)
2243                                         {
2244                                                 /* turn off RX */
2245                                                 isdnport->p_m_rxoff = 1;
2246                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
2247                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2248                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2249                                                 return(1);
2250                                         }
2251                                 }
2252                                 /* recording */
2253                                 if (isdnport->p_record)
2254                                 {
2255                                         /* txdata IS required */
2256                                         if (!isdnport->p_m_txdata)
2257                                         {
2258                                                 /* turn on RX */
2259                                                 isdnport->p_m_txdata = 1;
2260                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
2261                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2262                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
2263                                                 return(1);
2264                                         }
2265                                 } else
2266                                 {
2267                                         /* txdata NOT required */
2268                                         if (isdnport->p_m_txdata)
2269                                         {
2270                                                 /* turn off RX */
2271                                                 isdnport->p_m_txdata = 0;
2272                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
2273                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2274                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2275                                                 return(1);
2276                                         }
2277                                 }
2278                         }
2279
2280                         /* handle message from bchannel */
2281                         if (mISDNport->b_socket[i] > -1)
2282                         {
2283                                 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
2284                                 if (ret >= (int)MISDN_HEADER_LEN)
2285                                 {
2286                                         work = 1;
2287                                         switch(hh->prim)
2288                                         {
2289                                                 /* we don't care about confirms, we use rx data to sync tx */
2290                                                 case PH_DATA_CNF:
2291                                                 break;
2292
2293                                                 /* we receive audio data, we respond to it AND we send tones */
2294                                                 case PH_DATA_IND:
2295                                                 case DL_DATA_IND:
2296                                                 case PH_DATA_REQ:
2297                                                 case DL_DATA_REQ:
2298                                                 case PH_CONTROL_IND:
2299                                                 if (mISDNport->b_port[i])
2300                                                         mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2301                                                 else
2302                                                         PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
2303                                                 break;
2304
2305                                                 case PH_ACTIVATE_IND:
2306                                                 case DL_ESTABLISH_IND:
2307                                                 case PH_ACTIVATE_CNF:
2308                                                 case DL_ESTABLISH_CNF:
2309                                                 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2310                                                 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2311                                                 break;
2312
2313                                                 case PH_DEACTIVATE_IND:
2314                                                 case DL_RELEASE_IND:
2315                                                 case PH_DEACTIVATE_CNF:
2316                                                 case DL_RELEASE_CNF:
2317                                                 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2318                                                 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2319                                                 break;
2320
2321                                                 default:
2322                                                 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
2323                                         }
2324                                 } else
2325                                 {
2326                                         if (ret < 0 && errno != EWOULDBLOCK)
2327                                                 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2328                                 }
2329                         }
2330                         
2331                         i++;
2332                 }
2333
2334                 /* handle queued up-messages (d-channel) */
2335                 while ((mb = mdequeue(&mISDNport->upqueue)))
2336                 {
2337                         l3m = &mb->l3;
2338                         switch(l3m->type)
2339                         {
2340                                 case MPH_ACTIVATE_IND:
2341                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2342                                 end_trace();
2343                                 mISDNport->l1link = 1;
2344                                 break;
2345         
2346                                 case MPH_DEACTIVATE_IND:
2347                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2348                                 end_trace();
2349                                 mISDNport->l1link = 0;
2350                                 break;
2351
2352                                 case MPH_INFORMATION_IND:
2353                                 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2354                                 switch (l3m->pid)
2355                                 {
2356                                         case L1_SIGNAL_LOS_ON:
2357                                         mISDNport->los = 1;
2358                                         break;
2359                                         case L1_SIGNAL_LOS_OFF:
2360                                         mISDNport->los = 0;
2361                                         break;
2362                                         case L1_SIGNAL_AIS_ON:
2363                                         mISDNport->ais = 1;
2364                                         break;
2365                                         case L1_SIGNAL_AIS_OFF:
2366                                         mISDNport->ais = 0;
2367                                         break;
2368                                         case L1_SIGNAL_RDI_ON:
2369                                         mISDNport->rdi = 1;
2370                                         break;
2371                                         case L1_SIGNAL_RDI_OFF:
2372                                         mISDNport->rdi = 0;
2373                                         break;
2374                                         case L1_SIGNAL_SLIP_TX:
2375                                         mISDNport->slip_tx++;
2376                                         break;
2377                                         case L1_SIGNAL_SLIP_RX:
2378                                         mISDNport->slip_rx++;
2379                                         break;
2380                                 }
2381                                 break;
2382
2383                                 case MT_L2ESTABLISH:
2384                                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2385                                 add_trace("tei", NULL, "%d", l3m->pid);
2386                                 end_trace();
2387                                 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2388                                 {
2389                                         if (mISDNport->l2establish)
2390                                         {
2391                                                 mISDNport->l2establish = 0;
2392                                                 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2393                                         }
2394                                         mISDNport->l2link = 1;
2395                                 }
2396                                 break;
2397
2398                                 case MT_L2RELEASE:
2399                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2400                                 add_trace("tei", NULL, "%d", l3m->pid);
2401                                 end_trace();
2402                                 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2403                                 {
2404                                         mISDNport->l2link = 0;
2405                                         if (mISDNport->l2hold)
2406                                         {
2407                                                 time(&mISDNport->l2establish);
2408                                                 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2409                                         }
2410                                 }
2411                                 break;
2412
2413                                 default:
2414                                 /* l3-data is sent to LCR */
2415                                 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2416                         }
2417                         /* free message */
2418                         free_l3_msg(l3m);
2419                 }
2420
2421 #if 0
2422                 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2423                 { ---}
2424                         PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2425                         mISDNport->l1timeout = 0;
2426 #endif
2427
2428                 /* layer 2 establish timer */
2429                 if (mISDNport->l2establish)
2430                 {
2431                         if (now-mISDNport->l2establish > 5)
2432                         {
2433                                 mISDNport->l2establish = 0;
2434                                 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2435                                 {
2436
2437                                         PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2438                                         mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2439                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2440                                         add_trace("tei", NULL, "%d", 0);
2441                                         end_trace();
2442                                         time(&mISDNport->l2establish);
2443                                         return(1);
2444                                 }
2445                         }
2446                 }
2447
2448
2449                 mISDNport = mISDNport->next;
2450         }
2451
2452         /* if we received at least one b-frame, we will return 1 */
2453         return(work);
2454 }
2455 #else
2456 int mISDN_handler(void)
2457 {
2458         int ret;
2459         struct mISDNport *mISDNport;
2460         class PmISDN *isdnport;
2461         int i;
2462         msg_t *msg;
2463         iframe_t *frm;
2464         msg_t *dmsg;
2465         mISDNuser_head_t *hh;
2466         net_stack_t *nst;
2467
2468         /* the que avoids loopbacks when replying to stack after receiving
2469          * from stack. */
2470         mISDNport = mISDNport_first;
2471         while(mISDNport)
2472         {
2473                 /* process turning on/off rx */
2474                 i = 0;
2475                 while(i < mISDNport->b_num)
2476                 {
2477                         /* process timer events for bchannel handling */
2478                         if (mISDNport->b_timer[i])
2479                         {
2480                                 if (mISDNport->b_timer[i] <= now_d)
2481                                         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2482                         }
2483                         isdnport=mISDNport->b_port[i];
2484                         if (isdnport)
2485                         {
2486                                 /* call bridges in user space OR crypto OR recording */
2487                                 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2488                                 {
2489                                         /* rx IS required */
2490                                         if (isdnport->p_m_rxoff)
2491                                         {
2492                                                 /* turn on RX */
2493                                                 isdnport->p_m_rxoff = 0;
2494                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
2495                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2496                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2497                                                 return(1);
2498                                         }
2499                                 } else
2500                                 {
2501                                         /* rx NOT required */
2502                                         if (!isdnport->p_m_rxoff)
2503                                         {
2504                                                 /* turn off RX */
2505                                                 isdnport->p_m_rxoff = 1;
2506                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
2507                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2508                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2509                                                 return(1);
2510                                         }
2511                                 }
2512                                 /* recording */
2513                                 if (isdnport->p_record)
2514                                 {
2515                                         /* txdata IS required */
2516                                         if (!isdnport->p_m_txdata)
2517                                         {
2518                                                 /* turn on RX */
2519                                                 isdnport->p_m_txdata = 1;
2520                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
2521 #ifndef OLD_MISDN
2522                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2523                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2524 #endif
2525                                                 return(1);
2526                                         }
2527                                 } else
2528                                 {
2529                                         /* txdata NOT required */
2530                                         if (isdnport->p_m_txdata)
2531                                         {
2532                                                 /* turn off RX */
2533                                                 isdnport->p_m_txdata = 0;
2534                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
2535 #ifndef OLD_MISDN
2536                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2537                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2538 #endif
2539                                                 return(1);
2540                                         }
2541                                 }
2542                         }
2543                         i++;
2544                 }
2545 #if 0
2546                 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2547                 { ---}
2548                         PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2549                         mISDNport->l1timeout = 0;
2550 #endif
2551
2552                 if (mISDNport->l2establish)
2553                 {
2554                         if (now-mISDNport->l2establish > 5)
2555                         {
2556                                 mISDNport->l2establish = 0;
2557                                 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2558                                 {
2559                                         if (mISDNport->ntmode)
2560                                         {
2561                                                 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2562                                                 time(&mISDNport->l2establish);
2563                                                 /* establish */
2564                                                 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2565                                                 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2566                                                         free_msg(dmsg);
2567                                         } else {
2568                                                 iframe_t act;
2569
2570                                                 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2571                                                 time(&mISDNport->l2establish);
2572                                                 /* establish */
2573                                                 act.prim = DL_ESTABLISH | REQUEST; 
2574                                                 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2575                                                 act.dinfo = 0;
2576                                                 act.len = 0;
2577                                                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2578                                         }
2579                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2580                                         add_trace("tei", NULL, "%d", 0);
2581                                         end_trace();
2582                                         time(&mISDNport->l2establish);
2583                                         return(1);
2584                                 }
2585                         }
2586                 }
2587                 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2588                 {
2589                         if (mISDNport->ntmode)
2590                         {
2591                                 hh = (mISDNuser_head_t *)dmsg->data;
2592                                 PDEBUG(DEBUG_ISDN, "sending queued NT l3-down-message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", hh->prim, hh->dinfo, dmsg->len);
2593                                 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2594                                         free_msg(dmsg);
2595                         } else
2596                         {
2597                                 frm = (iframe_t *)dmsg->data;
2598                                 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2599                                 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2600                                 PDEBUG(DEBUG_ISDN, "sending queued TE l3-down-message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, dmsg->len);
2601                                 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2602                                 free_msg(dmsg);
2603                         }
2604                         return(1);
2605                 }
2606                 mISDNport = mISDNport->next;
2607         } 
2608
2609         /* no device, no read */
2610         if (mISDNdevice < 0)
2611                 return(0);
2612
2613         /* get message from kernel */
2614         if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2615                 return(1);
2616         ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2617         if (ret < 0)
2618         {
2619                 free_msg(msg);
2620                 if (errno == EAGAIN)
2621                         return(0);
2622                 FATAL("Failed to do mISDN_read()\n");
2623         }
2624         if (!ret)
2625         {
2626                 free_msg(msg);
2627 //              printf("%s: ERROR: mISDN_read() returns nothing\n");
2628                 return(0);
2629         }
2630         msg->len = ret;
2631         frm = (iframe_t *)msg->data;
2632
2633         /* global prim */
2634         switch(frm->prim)
2635         {
2636                 case MGR_DELLAYER | CONFIRM:
2637                 case MGR_INITTIMER | CONFIRM:
2638                 case MGR_ADDTIMER | CONFIRM:
2639                 case MGR_DELTIMER | CONFIRM:
2640                 case MGR_REMOVETIMER | CONFIRM:
2641                 free_msg(msg);
2642                 return(1);
2643         }
2644
2645         /* handle timer events from mISDN for NT-stack
2646          * note: they do not associate with a stack */
2647         if (frm->prim == (MGR_TIMER | INDICATION))
2648         {
2649                 itimer_t *it;
2650
2651                 /* find mISDNport */
2652                 mISDNport = mISDNport_first;
2653                 while(mISDNport)
2654                 {
2655                         /* nt mode only */
2656                         if (mISDNport->ntmode)
2657                         {
2658                                 it = mISDNport->nst.tlist;
2659                                 /* find timer */
2660                                 while(it)
2661                                 {
2662                                         if (it->id == (int)frm->addr)
2663                                                 break;
2664                                         it = it->next;
2665                                 }
2666                                 if (it)
2667                                         break;
2668                         }
2669                         mISDNport = mISDNport->next;
2670                 }
2671                 if (mISDNport)
2672                 {
2673                         mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2674                                 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2675
2676                         PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2677                         test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2678                         ret = it->function(it->data);
2679                 } else
2680                 {
2681                         PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2682                 }
2683                 goto out;
2684         }
2685
2686         /* find the mISDNport that belongs to the stack */
2687         mISDNport = mISDNport_first;
2688         while(mISDNport)
2689         {
2690                 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2691                         break;
2692                 mISDNport = mISDNport->next;
2693         } 
2694         if (!mISDNport)
2695         {
2696                 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2697                 // show a list of all mISDNports and their address
2698 #if 0
2699                 mISDNport = mISDNport_first;
2700                 while(mISDNport)
2701                 {
2702                         PERROR(" port %s  %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2703                         mISDNport = mISDNport->next;
2704                 } 
2705 #endif
2706                 goto out;
2707         }
2708
2709         /* master stack */
2710         if (!(frm->addr&FLG_CHILD_STACK))
2711         {
2712                 /* d-message */
2713                 switch(frm->prim)
2714                 {
2715                         case MGR_SHORTSTATUS | INDICATION:
2716                         case MGR_SHORTSTATUS | CONFIRM:
2717                         switch(frm->dinfo) {
2718                                 case SSTATUS_L1_ACTIVATED:
2719                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2720                                 end_trace();
2721                                 goto ss_act;
2722                                 case SSTATUS_L1_DEACTIVATED:
2723                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2724                                 end_trace();
2725                                 goto ss_deact;
2726                                 case SSTATUS_L2_ESTABLISHED:
2727                                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2728                                 end_trace();
2729                                 goto ss_estab;
2730                                 case SSTATUS_L2_RELEASED:
2731                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2732                                 end_trace();
2733                                 goto ss_rel;
2734                         }
2735                         break;
2736
2737                         case PH_ACTIVATE | CONFIRM:
2738                         case PH_ACTIVATE | INDICATION:
2739                         l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2740                         end_trace();
2741                         if (mISDNport->ntmode)
2742                         {
2743                                 mISDNport->l1link = 1;
2744                                 setup_queue(mISDNport, 1);
2745                                 goto l1_msg;
2746                         }
2747                         ss_act:
2748                         mISDNport->l1link = 1;
2749                         setup_queue(mISDNport, 1);
2750                         break;
2751
2752                         case PH_DEACTIVATE | CONFIRM:
2753                         case PH_DEACTIVATE | INDICATION:
2754                         l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2755                         end_trace();
2756                         if (mISDNport->ntmode)
2757                         {
2758                                 mISDNport->l1link = 0;
2759                                 setup_queue(mISDNport, 0);
2760                                 goto l1_msg;
2761                         }
2762                         ss_deact:
2763                         mISDNport->l1link = 0;
2764                         setup_queue(mISDNport, 0);
2765                         break;
2766
2767                         case PH_CONTROL | CONFIRM:
2768                         case PH_CONTROL | INDICATION:
2769                         PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2770                         break;
2771
2772                         case DL_ESTABLISH | INDICATION:
2773                         case DL_ESTABLISH | CONFIRM:
2774                         l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2775                         end_trace();
2776                         if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2777                         ss_estab:
2778                         if (!mISDNport->ntmode || mISDNport->ptp)
2779                         {
2780                                 if (mISDNport->l2establish)
2781                                 {
2782                                         mISDNport->l2establish = 0;
2783                                         PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2784                                 }
2785                                 mISDNport->l2link = 1;
2786                         }
2787                         break;
2788
2789                         case DL_RELEASE | INDICATION:
2790                         case DL_RELEASE | CONFIRM:
2791                         l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2792                         end_trace();
2793                         if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2794                         ss_rel:
2795                         if (!mISDNport->ntmode || mISDNport->ptp)
2796                         {
2797                                 mISDNport->l2link = 0;
2798                                 if (mISDNport->l2hold)
2799                                 {
2800                                         time(&mISDNport->l2establish);
2801                                         PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2802                                 }
2803                         }
2804                         break;
2805
2806                         default:
2807                         l1_msg:
2808                         PDEBUG(DEBUG_STACK, "GOT d-msg from %s port %d prim 0x%x dinfo 0x%x addr 0x%x\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, frm->prim, frm->dinfo, frm->addr);
2809                         if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2810                         {
2811                                 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2812                         }
2813                         /* d-message */
2814                         if (mISDNport->ntmode)
2815                         {
2816                                 /* l1-data enters the nt-mode library */
2817                                 nst = &mISDNport->nst;
2818                                 if (nst->l1_l2(nst, msg))
2819                                         free_msg(msg);
2820                                 return(1);
2821                         } else
2822                         {
2823                                 /* l3-data is sent to pbx */
2824                                 if (stack2manager_te(mISDNport, msg))
2825                                         free_msg(msg);
2826                                 return(1);
2827                         }
2828                 }
2829         } else
2830         /* child stack */
2831         {
2832                 /* b-message */
2833                 switch(frm->prim)
2834                 {
2835                         /* we don't care about confirms, we use rx data to sync tx */
2836                         case PH_DATA | CONFIRM:
2837                         case DL_DATA | CONFIRM:
2838                         break;
2839
2840                         /* we receive audio data, we respond to it AND we send tones */
2841                         case PH_DATA | INDICATION:
2842                         case DL_DATA | INDICATION:
2843                         case PH_CONTROL | INDICATION:
2844                         case PH_SIGNAL | INDICATION:
2845                         i = 0;
2846                         while(i < mISDNport->b_num)
2847                         {
2848                                 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2849                                         break;
2850                                 i++;
2851                         }
2852                         if (i == mISDNport->b_num)
2853                         {
2854                                 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2855                                 break;
2856                         }
2857                         if (mISDNport->b_port[i])
2858                         {
2859 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2860                                 mISDNport->b_port[i]->bchannel_receive(frm);
2861                         } else
2862                                 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2863                         break;
2864
2865                         case PH_ACTIVATE | INDICATION:
2866                         case DL_ESTABLISH | INDICATION:
2867                         case PH_ACTIVATE | CONFIRM:
2868                         case DL_ESTABLISH | CONFIRM:
2869                         PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2870                         i = 0;
2871                         while(i < mISDNport->b_num)
2872                         {
2873                                 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2874                                         break;
2875                                 i++;
2876                         }
2877                         if (i == mISDNport->b_num)
2878                         {
2879                                 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2880                                 break;
2881                         }
2882                         bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2883                         break;
2884
2885                         case PH_DEACTIVATE | INDICATION:
2886                         case DL_RELEASE | INDICATION:
2887                         case PH_DEACTIVATE | CONFIRM:
2888                         case DL_RELEASE | CONFIRM:
2889                         PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2890                         i = 0;
2891                         while(i < mISDNport->b_num)
2892                         {
2893                                 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2894                                         break;
2895                                 i++;
2896                         }
2897                         if (i == mISDNport->b_num)
2898                         {
2899                                 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2900                                 break;
2901                         }
2902                         bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2903                         break;
2904
2905                         default:
2906                         PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2907                 }
2908         }
2909
2910         out:
2911         free_msg(msg);
2912         return(1);
2913 }
2914 #endif
2915
2916 #ifdef SOCKET_MISDN
2917 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2918 {
2919         /* IMPORTAINT:
2920          *
2921          * l3m must be queued, except for MT_ASSIGN
2922          *
2923          */
2924         struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2925         struct mbuffer *mb;
2926
2927         /* special MT_ASSIGN handling:
2928          *
2929          * if we request a PID from mlayer, we always do it while lcr is locked.
2930          * therefore we must check the MT_ASSIGN reply first before we lock.
2931          * this is because the MT_ASSIGN reply is received with the requesting
2932          * process, not by the mlayer thread!
2933          * this means, that the reply is sent during call of the request.
2934          * we must check if we get a reply and we know that we lcr is currently
2935          * locked.
2936          */
2937         if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2938         {
2939                 /* let's do some checking if someone changes stack behaviour */
2940                 if (mt_assign_pid != 0)
2941                         FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2942                 mt_assign_pid = pid;
2943                 return(0);
2944         }
2945         
2946         /* queue message, create, if required */
2947         if (!l3m)
2948         {
2949                 l3m = alloc_l3_msg();
2950                 if (!l3m)
2951                         FATAL("No memory for layer 3 message\n");
2952         }
2953         mb = container_of(l3m, struct mbuffer, l3);
2954         l3m->type = cmd;
2955         l3m->pid = pid;
2956         mqueue_tail(&mISDNport->upqueue, mb);
2957         return 0;
2958 }
2959
2960 #endif
2961
2962
2963 /*
2964  * global function to add a new card (port)
2965  */
2966 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2967 {
2968         int ret;
2969         struct mISDNport *mISDNport, **mISDNportp;
2970         int i, cnt;
2971         int pri, bri, pots;
2972         int nt, te;
2973 #ifdef SOCKET_MISDN
2974 //      struct mlayer3 *ml3;
2975         struct mISDN_devinfo devinfo;
2976         unsigned int protocol, prop;
2977
2978         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2979         if (ret < 0)
2980         {
2981                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2982                 return(NULL);
2983         }
2984 #else
2985         unsigned char buff[1025];
2986         iframe_t *frm = (iframe_t *)buff;
2987 //      interface_info_t ii;
2988         net_stack_t *nst;
2989         manager_t *mgr;
2990         layer_info_t li;
2991         stack_info_t *stinf;
2992
2993         /* query port's requirements */
2994         cnt = mISDN_get_stack_count(mISDNdevice);
2995 #endif
2996
2997         if (cnt <= 0)
2998         {
2999                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
3000                 return(NULL);
3001         }
3002         if (port>cnt || port<1)
3003         {
3004                 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
3005                 return(NULL);
3006         }
3007
3008         pri = bri = pots = nt = te = 0;
3009 #ifdef SOCKET_MISDN
3010         devinfo.id = port - 1;
3011         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
3012         if (ret < 0)
3013         {
3014                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3015                 return(NULL);
3016         }
3017         /* output the port info */
3018         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3019         {
3020                 bri = 1;
3021                 te = 1;
3022         }
3023         if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3024         {
3025                 bri = 1;
3026                 nt = 1;
3027         }
3028         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3029         {
3030                 pri = 1;
3031                 te = 1;
3032         }
3033         if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3034         {
3035                 pri = 1;
3036                 nt = 1;
3037         }
3038 #ifdef ISDN_P_FXS
3039         if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3040         {
3041                 pots = 1;
3042                 te = 1;
3043         }
3044 #endif
3045 #ifdef ISDN_P_FXO
3046         if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3047         {
3048                 pots = 1;
3049                 nt = 1;
3050         }
3051 #endif
3052         if (force_nt && !nt)
3053         {
3054                 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
3055                 return(NULL);
3056         }
3057         if (bri && pri)
3058         {
3059                 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
3060                 return(NULL);
3061         }
3062         if (pots && !bri && !pri)
3063         {
3064                 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
3065                 return(NULL);
3066         }
3067         if (!bri && !pri)
3068         {
3069                 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
3070                 return(NULL);
3071         }
3072         if (!nt && !te)
3073         {
3074                 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
3075                 return(NULL);
3076         }
3077         /* set NT by turning off TE */
3078         if (force_nt && nt)
3079                 te = 0;
3080         /* if TE an NT is supported (and not forced to NT), turn off NT */
3081         if (te && nt)
3082                 nt = 0;
3083 #else
3084         ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
3085         if (ret < 0)
3086         {
3087                 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
3088                 return(NULL);
3089         }
3090         stinf = (stack_info_t *)&frm->data.p;
3091         switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3092         {
3093                 case ISDN_PID_L0_TE_S0:
3094                 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
3095                 break;
3096                 case ISDN_PID_L0_NT_S0:
3097                 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
3098                 nt = 1;
3099                 break;
3100                 case ISDN_PID_L0_TE_E1:
3101                 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1  interface line\n");
3102                 pri = 1;
3103                 break;
3104                 case ISDN_PID_L0_NT_E1:
3105                 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1  interface port\n");
3106                 pri = 1;
3107                 nt = 1;
3108                 break;
3109                 default:
3110                 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
3111                 return(NULL);
3112         }
3113         if (nt)
3114         {
3115                 /* NT */
3116                 if (stinf->pid.protocol[1] == 0)
3117                 {
3118                         PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
3119                         return(NULL);
3120                 }
3121                 if (stinf->pid.protocol[2])
3122                 {
3123                         PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
3124                         return(NULL);
3125                 }
3126         }
3127         if (te)
3128         {
3129                 /* TE */
3130                 if (stinf->pid.protocol[1] == 0)
3131                 {
3132                         PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
3133                         return(NULL);
3134                 }
3135                 if (stinf->pid.protocol[2] == 0)
3136                 {
3137                         PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
3138                         return(NULL);
3139                 }
3140                 if (stinf->pid.protocol[3] == 0)
3141                 {
3142                         PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
3143                         return(NULL);
3144                 } else
3145                 {
3146                         switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3147                         {
3148                                 case ISDN_PID_L3_DSS1USER:
3149                                 break;
3150
3151                                 default:
3152                                 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
3153                                 return(NULL);
3154                         }
3155                 }
3156                 if (stinf->pid.protocol[4])
3157                 {
3158                         PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3159                         return(NULL);
3160                 }
3161         }
3162 #endif
3163
3164         /* add mISDNport structure */
3165         mISDNportp = &mISDNport_first;
3166         while(*mISDNportp)
3167                 mISDNportp = &((*mISDNportp)->next);
3168         mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3169         pmemuse++;
3170         *mISDNportp = mISDNport;
3171
3172         /* if pri, must set PTP */
3173         if (pri)
3174                 ptp = 1;
3175         
3176         /* set l2hold */
3177         switch (l2hold)
3178         {
3179                 case -1: // off
3180                 l2hold = 0;
3181                 break;
3182                 case 1: // on
3183                 l2hold = 1;
3184                 break;
3185                 default:
3186                 if (ptp)
3187                         l2hold = 1;
3188                 else
3189                         l2hold = 0;
3190                 break;
3191         }
3192                 
3193         /* allocate ressources of port */
3194 #ifdef SOCKET_MISDN
3195         /* open layer 3 and init upqueue */
3196         protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
3197         prop = (1 << MISDN_FLG_L2_CLEAN);
3198         if (ptp) // ptp forced
3199                prop |= (1 << MISDN_FLG_PTP);
3200         if (nt) // supports hold/retrieve on nt-mode
3201                prop |= (1 << MISDN_FLG_NET_HOLD);
3202         if (l2hold) // supports layer 2 hold
3203                prop |= (1 << MISDN_FLG_L2_HOLD);
3204         /* queue must be initializes, because l3-thread may send messages during open_layer3() */
3205         mqueue_init(&mISDNport->upqueue);
3206         mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
3207         if (!mISDNport->ml3)
3208         {
3209                 mqueue_purge(&mISDNport->upqueue);
3210                 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
3211                 start_trace(port,
3212                         interface,
3213                         NULL,
3214                         NULL,
3215                         DIRECTION_NONE,
3216                         CATEGORY_CH,
3217                         0,
3218                         "PORT (open failed)");
3219                 end_trace();
3220                 mISDNport_close(mISDNport);
3221                 return(NULL);
3222         }
3223
3224 #if 0
3225         /* if ntmode, establish L1 to send the tei removal during start */
3226         if (mISDNport->ntmode)
3227         {
3228                 iframe_t act;
3229                 /* L1 */
3230                 act.prim = PH_ACTIVATE | REQUEST; 
3231                 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3232                 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3233                 act.dinfo = 0;
3234                 act.len = 0;
3235                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3236                 usleep(10000); /* to be sure, that l1 is up */
3237         }
3238 #endif
3239
3240         SCPY(mISDNport->name, devinfo.name);
3241         mISDNport->b_num = devinfo.nrbchan;
3242 #else
3243         msg_queue_init(&mISDNport->downqueue);
3244         mISDNport->d_stid = stinf->id;
3245         PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3246
3247         /* create layer intance */
3248         memset(&li, 0, sizeof(li));
3249         UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3250         li.object_id = -1;
3251         li.extentions = 0;
3252         li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3253         li.pid.layermask = ISDN_LAYER((nt?2:4));
3254         li.st = mISDNport->d_stid;
3255         ret = mISDN_new_layer(mISDNdevice, &li);
3256         if (ret)
3257         {
3258                 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3259                 closeport:
3260                 mISDNport_close(mISDNport);
3261                 return(NULL);
3262         }
3263         mISDNport->upper_id = li.id;
3264         ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3265         if (ret)
3266         {
3267                 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3268                 goto closeport;
3269         }
3270         mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3271         if (mISDNport->lower_id < 0)
3272         {
3273                 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3274                 goto closeport;
3275         }
3276         mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3277         if (mISDNport->upper_id < 0)
3278         {
3279                 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3280                 goto closeport;
3281         }
3282         PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3283
3284         /* if ntmode, establish L1 to send the tei removal during start */
3285         if (mISDNport->ntmode)
3286         {
3287                 iframe_t act;
3288                 /* L1 */
3289                 act.prim = PH_ACTIVATE | REQUEST; 
3290                 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3291                 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3292                 act.dinfo = 0;
3293                 act.len = 0;
3294                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3295                 usleep(10000); /* to be sure, that l1 is up */
3296         }
3297
3298         /* create nst (nt-mode only) */
3299         if (nt)
3300         {
3301                 mgr = &mISDNport->mgr;
3302                 nst = &mISDNport->nst;
3303
3304                 mgr->nst = nst;
3305                 nst->manager = mgr;
3306
3307                 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3308                 nst->device = mISDNdevice;
3309                 nst->cardnr = port;
3310                 nst->d_stid = mISDNport->d_stid;
3311
3312                 nst->feature = FEATURE_NET_HOLD;
3313                 if (ptp)
3314                         nst->feature |= FEATURE_NET_PTP;
3315                 if (pri)
3316                         nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3317 #if 0
3318                 i = 0;
3319                 while(i < mISDNport->b_num)
3320                 {
3321                         nst->b_stid[i] = mISDNport->b_stid[i];
3322                         i++;
3323                 }
3324 #endif
3325                 nst->l1_id = mISDNport->lower_id;
3326                 nst->l2_id = mISDNport->upper_id;
3327
3328                 /* phd */       
3329                 msg_queue_init(&nst->down_queue);
3330
3331                 Isdnl2Init(nst);
3332                 Isdnl3Init(nst);
3333         }
3334
3335         mISDNport->b_num = stinf->childcnt;
3336 #endif
3337         mISDNport->portnum = port;
3338         mISDNport->ntmode = nt;
3339         mISDNport->pri = pri;
3340         mISDNport->ptp = ptp;
3341         mISDNport->l2hold = l2hold;
3342         PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3343         i = 0;
3344         while(i < mISDNport->b_num)
3345         {
3346                 mISDNport->b_state[i] = B_STATE_IDLE;
3347 #ifdef SOCKET_MISDN
3348                 mISDNport->b_socket[i] = -1;
3349 #else
3350                 mISDNport->b_stid[i] = stinf->child[i];
3351                 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3352 #endif
3353                 i++;
3354         }
3355
3356 #ifdef SOCKET_MISDN
3357         /* if ptp, pull up the link */
3358         if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
3359         {
3360                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
3361                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3362                 add_trace("tei", NULL, "%d", 0);
3363                 end_trace();
3364                 time(&mISDNport->l2establish);
3365         }
3366 #else
3367         /* if te-mode, query state link */
3368         if (!mISDNport->ntmode)
3369         {
3370                 iframe_t act;
3371                 /* L2 */
3372                 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3373                 act.prim = MGR_SHORTSTATUS | REQUEST; 
3374                 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3375                 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3376                 act.len = 0;
3377                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3378         }
3379         /* if ptp AND te-mode, pull up the link */
3380         if (mISDNport->l2hold && !mISDNport->ntmode)
3381         {
3382                 iframe_t act;
3383                 /* L2 */
3384                 act.prim = DL_ESTABLISH | REQUEST; 
3385                 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3386                 act.dinfo = 0;
3387                 act.len = 0;
3388                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3389
3390                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3391                 end_trace();
3392                 time(&mISDNport->l2establish);
3393         }
3394         /* if ptp AND nt-mode, pull up the link */
3395         if (mISDNport->l2hold && mISDNport->ntmode && mISDNport->ptp)
3396         {
3397                 msg_t *dmsg;
3398                 /* L2 */
3399                 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3400                 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3401                         free_msg(dmsg);
3402                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3403                 end_trace();
3404                 time(&mISDNport->l2establish);
3405         }
3406 #endif
3407
3408         /* initially, we assume that the link is down, exept for nt-ptmp */
3409         mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3410
3411         PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3412
3413         start_trace(mISDNport->portnum,
3414                     interface,
3415                     NULL,
3416                     NULL,
3417                     DIRECTION_NONE,
3418                     CATEGORY_CH,
3419                     0,
3420                     "PORT (open)");
3421         add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
3422         add_trace("channels", NULL, "%d", mISDNport->b_num);
3423         end_trace();
3424         return(mISDNport);
3425 }
3426
3427
3428 /*
3429  * function to free ALL cards (ports)
3430  */
3431 void mISDNport_close_all(void)
3432 {
3433         /* free all ports */
3434         while(mISDNport_first)
3435                 mISDNport_close(mISDNport_first);
3436 }
3437
3438 /*
3439  * free only one port
3440  */
3441 void mISDNport_close(struct mISDNport *mISDNport)
3442 {
3443         struct mISDNport **mISDNportp;
3444         class Port *port;
3445         class PmISDN *isdnport;
3446 #ifdef SOCKET_MISDN
3447 #else
3448         net_stack_t *nst;
3449         unsigned char buf[32];
3450 #endif
3451         int i;
3452
3453         /* remove all port instance that are linked to this mISDNport */
3454         port = port_first;
3455         while(port)
3456         {
3457                 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3458                 {
3459                         isdnport = (class PmISDN *)port;
3460                         if (isdnport->p_m_mISDNport)
3461                         {
3462                                 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3463                                 delete isdnport;
3464                         }
3465                 }
3466                 port = port->next;
3467         }
3468
3469         /* only if we are already part of interface */
3470         if (mISDNport->ifport)
3471         {
3472                 start_trace(mISDNport->portnum,
3473                             mISDNport->ifport->interface,
3474                             NULL,
3475                             NULL,
3476                             DIRECTION_NONE,
3477                             CATEGORY_CH,
3478                             0,
3479                             "PORT (close)");
3480                 end_trace();
3481         }
3482
3483         /* free bchannels */
3484         i = 0;
3485         while(i < mISDNport->b_num)
3486         {
3487 #ifdef SOCKET_MISDN
3488                 if (mISDNport->b_socket[i] > -1)
3489 #else
3490                 if (mISDNport->b_addr[i])
3491 #endif
3492                 {
3493                         _bchannel_destroy(mISDNport, i);
3494                         PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3495                 }
3496                 i++;
3497         }
3498
3499 #ifdef SOCKET_MISDN
3500         /* close layer 3, if open and purge upqueue */
3501         if (mISDNport->ml3)
3502         {
3503                 close_layer3(mISDNport->ml3);
3504                 mqueue_purge(&mISDNport->upqueue);
3505         }
3506 #else
3507         /* free ressources of port */
3508         msg_queue_purge(&mISDNport->downqueue);
3509
3510         /* free stacks */
3511         if (mISDNport->ntmode)
3512         {
3513                 nst = &mISDNport->nst;
3514                 if (nst->manager) /* to see if initialized */
3515                 {
3516                         PDEBUG(DEBUG_STACK, "the following messages are ok: one L3 process always exists (broadcast process) and some L2 instances (broadcast + current telephone's instances)\n");
3517                         cleanup_Isdnl3(nst);
3518                         cleanup_Isdnl2(nst);
3519
3520                         /* phd */
3521                         msg_queue_purge(&nst->down_queue);
3522                         if (nst->phd_down_msg)
3523                                 FREE(nst->phd_down_msg, 0);
3524                 }
3525         }
3526
3527         PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3528         if (mISDNport->d_stid)
3529         {
3530                 if (mISDNport->upper_id)
3531                         mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3532         }
3533 #endif
3534
3535         /* remove from list */
3536         mISDNportp = &mISDNport_first;
3537         while(*mISDNportp)
3538         {
3539                 if (*mISDNportp == mISDNport)
3540                 {
3541                         *mISDNportp = (*mISDNportp)->next;
3542                         mISDNportp = NULL;
3543                         break;
3544                 }
3545                 mISDNportp = &((*mISDNportp)->next);
3546         }
3547
3548         if (mISDNportp)
3549                 FATAL("mISDNport not in list\n");
3550         
3551         FREE(mISDNport, sizeof(struct mISDNport));
3552         pmemuse--;
3553
3554 }
3555
3556
3557 /*
3558  * global function to show all available isdn ports
3559  */
3560 void mISDN_port_info(void)
3561 {
3562         int ret;
3563         int i, ii;
3564         int useable, nt, te, pri, bri, pots;
3565 #ifdef SOCKET_MISDN
3566         struct mISDN_devinfo devinfo;
3567         int sock;
3568
3569         /* open mISDN */
3570         sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3571         if (sock < 0)
3572         {
3573                 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3574                 exit(EXIT_FAILURE);
3575         }
3576
3577         /* get number of stacks */
3578         i = 1;
3579         ret = ioctl(sock, IMGETCOUNT, &ii);
3580         if (ret < 0)
3581         {
3582                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3583                 goto done;
3584         }
3585 #else
3586         int p;
3587         unsigned char buff[1025];
3588         iframe_t *frm = (iframe_t *)buff;
3589         stack_info_t *stinf;
3590         int device;
3591
3592         /* open mISDN */
3593         if ((device = mISDN_open()) < 0)
3594         {
3595                 fprintf(stderr, "Cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", device, errno, strerror(errno));
3596                 exit(EXIT_FAILURE);
3597         }
3598
3599         /* get number of stacks */
3600         i = 1;
3601         ii = mISDN_get_stack_count(device);
3602 #endif
3603         printf("\n");
3604         if (ii <= 0)
3605         {
3606                 printf("Found no card. Please be sure to load card drivers.\n");
3607                 goto done;
3608         }
3609
3610         /* loop the number of cards and get their info */
3611         while(i <= ii)
3612         {
3613                 nt = te = bri = pri = pots = 0;
3614                 useable = 0;
3615
3616 #ifdef SOCKET_MISDN
3617                 devinfo.id = i - 1;
3618                 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
3619                 if (ret < 0)
3620                 {
3621                         fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3622                         break;
3623                 }
3624
3625                 /* output the port info */
3626                 printf("Port %2d name='%s': ", i, devinfo.name);
3627                 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3628                 {
3629                         bri = 1;
3630                         te = 1;
3631                 }
3632                 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3633                 {
3634                         bri = 1;
3635                         nt = 1;
3636                 }
3637                 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3638                 {
3639                         pri = 1;
3640                         te = 1;
3641                 }
3642                 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3643                 {
3644                         pri = 1;
3645                         nt = 1;
3646                 }
3647 #ifdef ISDN_P_FXS
3648                 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3649                 {
3650                         pots = 1;
3651                         te = 1;
3652                 }
3653 #endif
3654 #ifdef ISDN_P_FXO
3655                 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3656                 {
3657                         pots = 1;
3658                         nt = 1;
3659                 }
3660 #endif
3661                 if ((te || nt) && (bri || pri || pots))
3662                         useable = 1;
3663
3664                 if (te && nt && bri)
3665                         printf("TE/NT-mode BRI S/T (for phone lines & phones)");
3666                 if (te && !nt && bri)
3667                         printf("TE-mode    BRI S/T (for phone lines)");
3668                 if (nt && !te && bri)
3669                         printf("NT-mode    BRI S/T (for phones)");
3670                 if (te && nt && pri)
3671                         printf("TE/NT-mode PRI E1  (for phone lines & E1 devices)");
3672                 if (te && !nt && pri)
3673                         printf("TE-mode    PRI E1  (for phone lines)");
3674                 if (nt && !te && pri)
3675                         printf("NT-mode    PRI E1  (for E1 devices)");
3676                 if (te && nt && pots)
3677                         printf("FXS/FXO    POTS    (for analog lines & phones)");
3678                 if (te && !nt && pots)
3679                         printf("FXS        POTS    (for analog lines)");
3680                 if (nt && !te && pots)
3681                         printf("FXO        POTS    (for analog phones)");
3682                 if (pots)
3683                 {
3684                         useable = 0;
3685                         printf("\n -> Analog interfaces are not supported.");
3686                 } else
3687                 if (!useable)
3688                 {
3689                         printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3690                 }
3691                 printf("\n");
3692
3693                 printf("  - %d B-channels\n", devinfo.nrbchan);
3694 #else
3695                 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3696                 if (ret <= 0)
3697                 {
3698                         fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3699                         break;
3700                 }
3701                 stinf = (stack_info_t *)&frm->data.p;
3702
3703                 /* output the port info */
3704                 printf("Port %2d: ", i);
3705                 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3706                 {
3707                         case ISDN_PID_L0_TE_S0:
3708                         useable = 1;
3709                         te = 1;
3710                         bri = 1;
3711                         printf("TE-mode BRI S/T interface line (for phone lines)");
3712                         break;
3713                         case ISDN_PID_L0_NT_S0:
3714                         useable = 1;
3715                         nt = 1;
3716                         bri = 1;
3717                         printf("NT-mode BRI S/T interface port (for phones)");
3718                         break;
3719                         case ISDN_PID_L0_TE_E1:
3720                         useable = 1;
3721                         te = 1;
3722                         pri = 1;
3723                         printf("TE-mode PRI E1  interface line (for phone lines)");
3724                         break;
3725                         case ISDN_PID_L0_NT_E1:
3726                         useable = 1;
3727                         nt = 1;
3728                         pri = 1;
3729                         printf("NT-mode PRI E1  interface port (for E1 devices)");
3730                         break;
3731                         default:
3732                         useable = 0;
3733                         printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3734                 }
3735                 printf("\n");
3736
3737                 if (nt)
3738                 {
3739                         if (stinf->pid.protocol[1] == 0)
3740                         {
3741                                 useable = 0;
3742                                 printf(" -> Missing layer 1 NT-mode protocol.\n");
3743                         }
3744                         p = 2;
3745                         while(p <= MAX_LAYER_NR) {
3746                                 if (stinf->pid.protocol[p])
3747                                 {
3748                                         useable = 0;
3749                                         printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3750                                 }
3751                                 p++;
3752                         }
3753                         if (useable)
3754                         {
3755                                 if (pri)
3756                                         printf(" -> Interface is Point-To-Point (PRI).\n");
3757                                 else
3758                                         printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3759                         }
3760                 }
3761                 if (te)
3762                 {
3763                         if (stinf->pid.protocol[1] == 0)
3764                         {
3765                                 useable = 0;
3766                                 printf(" -> Missing layer 1 protocol.\n");
3767                         }
3768                         if (stinf->pid.protocol[2] == 0)
3769                         {
3770                                 useable = 0;
3771                                 printf(" -> Missing layer 2 protocol.\n");
3772                         }
3773                         if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3774                         {
3775                                 printf(" -> Interface is Poin-To-Point.\n");
3776                         }
3777                         if (stinf->pid.protocol[3] == 0)
3778                         {
3779                                 useable = 0;
3780                                 printf(" -> Missing layer 3 protocol.\n");
3781                         } else
3782                         {
3783                                 printf(" -> Protocol: ");
3784                                 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3785                                 {
3786                                         case ISDN_PID_L3_DSS1USER:
3787                                         printf("DSS1 (Euro ISDN)");
3788                                         break;
3789
3790                                         default:
3791                                         useable = 0;
3792                                         printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3793                                 }
3794                                 printf("\n");
3795                         }
3796                         p = 4;
3797                         while(p <= MAX_LAYER_NR) {
3798                                 if (stinf->pid.protocol[p])
3799                                 {
3800                                         useable = 0;
3801                                         printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3802                                 }
3803                                 p++;
3804                         }
3805                 }
3806                 printf("  - %d B-channels\n", stinf->childcnt);
3807 #endif
3808
3809                 if (!useable)
3810                         printf(" * Port NOT useable for LCR\n");
3811
3812                 printf("--------\n");
3813
3814                 i++;
3815         }
3816         printf("\n");
3817
3818 done:
3819 #ifdef SOCKET_MISDN
3820         close(sock);
3821 #else
3822         /* close mISDN */
3823         if ((ret = mISDN_close(device)))
3824                 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3825 #endif
3826 }
3827
3828
3829 /*
3830  * enque data from upper buffer
3831  */
3832 void PmISDN::txfromup(unsigned char *data, int length)
3833 {
3834 #ifdef SOCKET_MISDN
3835         unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3836         struct mISDNhead *hh = (struct mISDNhead *)buf;
3837         int ret;
3838
3839         if (p_m_b_index < 0)
3840                 return;
3841         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
3842                 return;
3843 #else
3844         unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3845         iframe_t *frm = (iframe_t *)buf;
3846
3847         if (p_m_b_index < 0)
3848                 return;
3849         if (!p_m_mISDNport->b_addr[p_m_b_index])
3850                 return;
3851 #endif
3852
3853         /* check if high priority tones exist
3854          * ignore data in this case
3855          */
3856         if (p_tone_name[0] || p_m_crypt_msg_loops)
3857                 return;
3858
3859         /* preload procedure
3860          * if transmit buffer in DSP module is empty,
3861          * preload it to DSP_LOAD to prevent jitter gaps.
3862          */
3863         if (p_m_load==0 && ISDN_LOAD>0)
3864         {
3865 #ifdef SOCKET_MISDN
3866                 hh->prim = PH_DATA_REQ; 
3867                 hh->id = 0;
3868                 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3869                 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
3870                 if (ret <= 0)
3871                         PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3872 #else
3873                 frm->prim = DL_DATA | REQUEST; 
3874                 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3875                 frm->dinfo = 0;
3876                 frm->len = ISDN_LOAD;
3877                 memset(buf+mISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3878                 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+ISDN_LOAD, TIMEOUT_1SEC);
3879 #endif
3880                 p_m_load += ISDN_LOAD;
3881         }
3882
3883         /* drop if load would exceed ISDN_MAXLOAD
3884          * this keeps the delay not too high
3885          */
3886         if (p_m_load+length > ISDN_MAXLOAD)
3887                 return;
3888
3889         /* make and send frame */
3890 #ifdef SOCKET_MISDN
3891         hh->prim = PH_DATA_REQ;
3892         hh->id = 0;
3893         memcpy(buf+MISDN_HEADER_LEN, data, length);
3894         ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3895         if (ret <= 0)
3896                 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3897 #else
3898         frm->prim = DL_DATA | REQUEST; 
3899         frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3900         frm->dinfo = 0;
3901         frm->len = length;
3902         memcpy(buf+mISDN_HEADER_LEN, data, length);
3903         mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3904 #endif
3905         p_m_load += length;
3906 }
3907