some minor fixes
[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 #ifdef SOCKET_MISDN
1750                         case DSP_TX_DATA:
1751 #else
1752                         case CMX_TX_DATA:
1753 #endif
1754                         if (!p_m_txdata)
1755                         {
1756                                 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1757                                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1758                                 return;
1759                         }
1760                         /* see below (same condition) */
1761                         if (p_state!=PORT_STATE_CONNECT
1762                                  && !p_m_mISDNport->tones)
1763                                 break;
1764 //                      printf(".");fflush(stdout);return;
1765                         if (p_record)
1766                                 record(data, len, 1); // from up
1767                         break;
1768 #endif
1769
1770                         default:
1771                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1772 #ifdef SOCKET_MISDN
1773                         add_trace("unknown", NULL, "0x%x", hh->id);
1774 #else
1775                         add_trace("unknown", NULL, "0x%x", frm->dinfo);
1776 #endif
1777                         end_trace();
1778                 }
1779                 return;
1780         }
1781 #ifdef SOCKET_MISDN
1782         if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1783         {
1784                 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1785 #else
1786         if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1787         {
1788                 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1789 #endif
1790                 return;
1791         }
1792         /* calls will not process any audio data unless
1793          * the call is connected OR interface features audio during call setup.
1794          */
1795 //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);     
1796 #ifndef DEBUG_COREBRIDGE
1797         if (p_state!=PORT_STATE_CONNECT
1798          && !p_m_mISDNport->tones)
1799                 return;
1800 #endif
1801
1802         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1803         if (p_m_rxoff)
1804         {
1805                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1806                 return;
1807         }
1808
1809         /* record data */
1810         if (p_record)
1811                 record(data, len, 0); // from down
1812
1813         /* randomize and listen to crypt message if enabled */
1814         if (p_m_crypt_listen)
1815         {
1816                 /* the noisy randomizer */
1817                 p = data;
1818                 l = len;
1819                 while(l--)
1820                         mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1821
1822                 cryptman_listen_bch(data, len);
1823         }
1824
1825         p = data;
1826
1827         /* send data to epoint */
1828         if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1829         {
1830                 length_temp = len;
1831                 data_temp = p;
1832                 while(length_temp)
1833                 {
1834                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1835                         message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1836                         memcpy(message->param.data.data, data_temp, message->param.data.len);
1837                         message_put(message);
1838                         if (length_temp <= sizeof(message->param.data.data))
1839                                 break;
1840                         data_temp += sizeof(message->param.data.data);
1841                         length_temp -= sizeof(message->param.data.data);
1842                 }
1843         }
1844 }
1845
1846
1847 /*
1848  * set echotest
1849  */
1850 void PmISDN::set_echotest(int echo)
1851 {
1852         if (p_m_echo != echo)
1853         {
1854                 p_m_echo = echo;
1855                 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1856                 if (p_m_b_channel)
1857                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1858 #ifdef SOCKET_MISDN
1859                                 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);
1860 #else
1861                                 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);
1862 #endif
1863         }
1864 }
1865
1866 /*
1867  * set tone
1868  */
1869 void PmISDN::set_tone(char *dir, char *tone)
1870 {
1871         int id;
1872
1873         if (!tone)
1874                 tone = "";
1875         PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1876         if (!tone[0])
1877         {
1878                 id = TONE_OFF;
1879                 goto setdsp;
1880         }
1881
1882         /* check if we NOT really have to use a dsp-tone */
1883         if (!options.dsptones)
1884         {
1885                 nodsp:
1886                 if (p_m_tone)
1887                 if (p_m_b_index > -1)
1888                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1889                 {
1890                         PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1891 #ifdef SOCKET_MISDN
1892                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1893 #else
1894                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1895 #endif
1896                 }
1897                 p_m_tone = 0;
1898                 Port::set_tone(dir, tone);
1899                 return;
1900         }
1901         if (p_tone_dir[0])
1902                 goto nodsp;
1903
1904         /* now we USE dsp-tone, convert name */
1905         else if (!strcmp(tone, "dialtone"))
1906         {
1907                 switch(options.dsptones) {
1908                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1909                 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1910                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1911                 }
1912         } else if (!strcmp(tone, "dialpbx"))
1913         {
1914                 switch(options.dsptones) {
1915                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1916                 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1917                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1918                 }
1919         } else if (!strcmp(tone, "ringing"))
1920         {
1921                 switch(options.dsptones) {
1922                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1923                 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1924                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1925                 }
1926         } else if (!strcmp(tone, "ringpbx"))
1927         {
1928                 switch(options.dsptones) {
1929                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1930                 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1931                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1932                 }
1933         } else if (!strcmp(tone, "busy"))
1934         {
1935                 busy:
1936                 switch(options.dsptones) {
1937                 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1938                 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1939                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1940                 }
1941         } else if (!strcmp(tone, "release"))
1942         {
1943                 hangup:
1944                 switch(options.dsptones) {
1945                 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1946                 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1947                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1948                 }
1949         } else if (!strcmp(tone, "cause_10"))
1950                 goto hangup;
1951         else if (!strcmp(tone, "cause_11"))
1952                 goto busy;
1953         else if (!strcmp(tone, "cause_22"))
1954         {
1955                 switch(options.dsptones) {
1956                 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1957                 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1958                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1959                 }
1960         } else if (!strncmp(tone, "cause_", 6))
1961                 id = TONE_SPECIAL_INFO;
1962         else
1963                 id = TONE_OFF;
1964
1965         /* if we have a tone that is not supported by dsp */
1966         if (id==TONE_OFF && tone[0])
1967                 goto nodsp;
1968
1969         setdsp:
1970         if (p_m_tone != id)
1971         {
1972                 /* set new tone */
1973                 p_m_tone = id;
1974                 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1975                 if (p_m_b_index > -1)
1976                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1977 #ifdef SOCKET_MISDN
1978                         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);
1979 #else
1980                         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);
1981 #endif
1982         }
1983         /* turn user-space tones off in cases of no tone OR dsp tone */
1984         Port::set_tone("",NULL);
1985 }
1986
1987
1988 /* MESSAGE_mISDNSIGNAL */
1989 //extern struct lcr_msg *dddebug;
1990 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1991 {
1992         switch(param->mISDNsignal.message)
1993         {
1994                 case mISDNSIGNAL_VOLUME:
1995                 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1996                 {
1997                         p_m_tx_gain = param->mISDNsignal.tx_gain;
1998                         PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1999                         if (p_m_b_index > -1)
2000                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2001 #ifdef SOCKET_MISDN
2002                                 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);
2003 #else
2004                                 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);
2005 #endif
2006                 } else
2007                         PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
2008                 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
2009                 {
2010                         p_m_rx_gain = param->mISDNsignal.rx_gain;
2011                         PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
2012                         if (p_m_b_index > -1)
2013                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2014 #ifdef SOCKET_MISDN
2015                                 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);
2016 #else
2017                                 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);
2018 #endif
2019                 } else
2020                         PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
2021                 break;
2022
2023                 case mISDNSIGNAL_CONF:
2024 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2025 //tone          if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
2026                 if (p_m_conf != param->mISDNsignal.conf)
2027                 {
2028                         p_m_conf = param->mISDNsignal.conf;
2029                         PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
2030                         if (p_m_b_index > -1)
2031                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2032 #ifdef SOCKET_MISDN
2033                                 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);
2034 #else
2035                                 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);
2036 #endif
2037                 } else
2038                         PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
2039                 /* we must set, even if currently tone forbids conf */
2040                 p_m_conf = param->mISDNsignal.conf;
2041 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2042                 break;
2043
2044                 case mISDNSIGNAL_JOINDATA:
2045                 if (p_m_joindata != param->mISDNsignal.joindata)
2046                 {
2047                         p_m_joindata = param->mISDNsignal.joindata;
2048                         PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
2049                 } else
2050                         PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
2051                 break;
2052                 
2053                 case mISDNSIGNAL_DELAY:
2054                 if (p_m_delay != param->mISDNsignal.delay)
2055                 {
2056                         p_m_delay = param->mISDNsignal.delay;
2057                         PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
2058 #ifndef OLD_MISDN
2059                         if (p_m_b_index > -1)
2060                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2061 #ifdef SOCKET_MISDN
2062                                 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);
2063 #else
2064                                 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);
2065 #endif
2066 #endif
2067                 } else
2068                         PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
2069                 break;
2070
2071                 default:
2072                 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
2073         }
2074 }
2075
2076 /* MESSAGE_CRYPT */
2077 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
2078 {
2079         struct lcr_msg *message;
2080
2081         switch(param->crypt.type)
2082         {
2083                 case CC_ACTBF_REQ:           /* activate blowfish */
2084                 p_m_crypt = 1;
2085                 p_m_crypt_key_len = param->crypt.len;
2086                 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
2087                 {
2088                         PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
2089                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
2090                         message->param.crypt.type = CC_ERROR_IND;
2091                         message_put(message);
2092                         break;
2093                 }
2094                 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
2095                 crypt_off:
2096                 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
2097                 if (p_m_b_index > -1)
2098                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2099 #ifdef SOCKET_MISDN
2100                         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);
2101 #else
2102                         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);
2103 #endif
2104                 break;
2105
2106                 case CC_DACT_REQ:            /* deactivate session encryption */
2107                 p_m_crypt = 0;
2108                 goto crypt_off;
2109                 break;
2110
2111                 case CR_LISTEN_REQ:          /* start listening to messages */
2112                 p_m_crypt_listen = 1;
2113                 p_m_crypt_listen_state = 0;
2114                 break;
2115
2116                 case CR_UNLISTEN_REQ:        /* stop listening to messages */
2117                 p_m_crypt_listen = 0;
2118                 break;
2119
2120                 case CR_MESSAGE_REQ:         /* send message */
2121                 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2122                 if (!p_m_crypt_msg_len)
2123                 {
2124                         PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2125                         break;
2126                 }
2127                 p_m_crypt_msg_current = 0; /* reset */
2128                 p_m_crypt_msg_loops = 6; /* enable */
2129 #if 0
2130                 /* disable txmix, or we get corrupt data due to audio process */
2131                 if (p_m_txmix && p_m_b_index>=0)
2132                 {
2133                         PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2134 #ifdef SOCKET_MISDN
2135                         ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
2136 #else
2137                         ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2138 #endif
2139                 }
2140 #endif
2141                 break;
2142
2143                 default:
2144                 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2145         }
2146
2147 }
2148
2149 /*
2150  * endpoint sends messages to the port
2151  */
2152 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2153 {
2154         if (Port::message_epoint(epoint_id, message_id, param))
2155                 return(1);
2156
2157         switch(message_id)
2158         {
2159                 case MESSAGE_DATA: /* tx-data from upper layer */
2160                 txfromup(param->data.data, param->data.len);
2161                 return(1);
2162
2163                 case MESSAGE_mISDNSIGNAL: /* user command */
2164                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2165                 message_mISDNsignal(epoint_id, message_id, param);
2166                 return(1);
2167
2168                 case MESSAGE_CRYPT: /* crypt control command */
2169                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2170                 message_crypt(epoint_id, message_id, param);
2171                 return(1);
2172         }
2173
2174         return(0);
2175 }
2176
2177
2178 /*
2179  * main loop for processing messages from mISDN
2180  */
2181 #ifdef SOCKET_MISDN
2182 int mISDN_handler(void)
2183 {
2184         int ret, work = 0;
2185         struct mISDNport *mISDNport;
2186         class PmISDN *isdnport;
2187         int i;
2188         unsigned char buffer[2048+MISDN_HEADER_LEN];
2189         struct mISDNhead *hh = (struct mISDNhead *)buffer;
2190         struct mbuffer *mb;
2191         struct l3_msg *l3m;
2192
2193         /* process all ports */
2194         mISDNport = mISDNport_first;
2195         while(mISDNport)
2196         {
2197                 /* process all bchannels */
2198                 i = 0;
2199                 while(i < mISDNport->b_num)
2200                 {
2201                         /* process timer events for bchannel handling */
2202                         if (mISDNport->b_timer[i])
2203                         {
2204                                 if (mISDNport->b_timer[i] <= now_d)
2205                                         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2206                         }
2207                         /* handle port of bchannel */
2208                         isdnport=mISDNport->b_port[i];
2209                         if (isdnport)
2210                         {
2211                                 /* call bridges in user space OR crypto OR recording */
2212                                 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2213                                 {
2214                                         /* rx IS required */
2215                                         if (isdnport->p_m_rxoff)
2216                                         {
2217                                                 /* turn on RX */
2218                                                 isdnport->p_m_rxoff = 0;
2219                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
2220                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2221                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2222                                                 return(1);
2223                                         }
2224                                 } else
2225                                 {
2226                                         /* rx NOT required */
2227                                         if (!isdnport->p_m_rxoff)
2228                                         {
2229                                                 /* turn off RX */
2230                                                 isdnport->p_m_rxoff = 1;
2231                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
2232                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2233                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2234                                                 return(1);
2235                                         }
2236                                 }
2237                                 /* recording */
2238                                 if (isdnport->p_record)
2239                                 {
2240                                         /* txdata IS required */
2241                                         if (!isdnport->p_m_txdata)
2242                                         {
2243                                                 /* turn on RX */
2244                                                 isdnport->p_m_txdata = 1;
2245                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
2246                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2247                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
2248                                                 return(1);
2249                                         }
2250                                 } else
2251                                 {
2252                                         /* txdata NOT required */
2253                                         if (isdnport->p_m_txdata)
2254                                         {
2255                                                 /* turn off RX */
2256                                                 isdnport->p_m_txdata = 0;
2257                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
2258                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2259                                                         ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2260                                                 return(1);
2261                                         }
2262                                 }
2263                         }
2264
2265                         /* handle message from bchannel */
2266                         if (mISDNport->b_socket[i] > -1)
2267                         {
2268                                 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
2269                                 if (ret >= (int)MISDN_HEADER_LEN)
2270                                 {
2271                                         work = 1;
2272                                         switch(hh->prim)
2273                                         {
2274                                                 /* we don't care about confirms, we use rx data to sync tx */
2275                                                 case PH_DATA_CNF:
2276                                                 break;
2277
2278                                                 /* we receive audio data, we respond to it AND we send tones */
2279                                                 case PH_DATA_IND:
2280                                                 case DL_DATA_IND:
2281                                                 case PH_CONTROL_IND:
2282                                                 if (mISDNport->b_port[i])
2283                                                         mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2284                                                 else
2285                                                         PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
2286                                                 break;
2287
2288                                                 case PH_ACTIVATE_IND:
2289                                                 case DL_ESTABLISH_IND:
2290                                                 case PH_ACTIVATE_CNF:
2291                                                 case DL_ESTABLISH_CNF:
2292                                                 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2293                                                 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2294                                                 break;
2295
2296                                                 case PH_DEACTIVATE_IND:
2297                                                 case DL_RELEASE_IND:
2298                                                 case PH_DEACTIVATE_CNF:
2299                                                 case DL_RELEASE_CNF:
2300                                                 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2301                                                 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2302                                                 break;
2303
2304                                                 default:
2305                                                 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
2306                                         }
2307                                 } else
2308                                 {
2309                                         if (ret < 0 && errno != EWOULDBLOCK)
2310                                                 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2311                                 }
2312                         }
2313                         
2314                         i++;
2315                 }
2316
2317                 /* handle queued up-messages (d-channel) */
2318                 while ((mb = mdequeue(&mISDNport->upqueue)))
2319                 {
2320                         l3m = &mb->l3;
2321                         switch(l3m->type)
2322                         {
2323                                 case MPH_ACTIVATE_IND:
2324                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2325                                 end_trace();
2326                                 mISDNport->l1link = 1;
2327                                 break;
2328         
2329                                 case MPH_DEACTIVATE_IND:
2330                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2331                                 end_trace();
2332                                 mISDNport->l1link = 0;
2333                                 break;
2334
2335                                 case MPH_INFORMATION_IND:
2336                                 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2337                                 switch (l3m->pid)
2338                                 {
2339                                         case L1_SIGNAL_LOS_ON:
2340                                         mISDNport->los = 1;
2341                                         break;
2342                                         case L1_SIGNAL_LOS_OFF:
2343                                         mISDNport->los = 0;
2344                                         break;
2345                                         case L1_SIGNAL_AIS_ON:
2346                                         mISDNport->ais = 1;
2347                                         break;
2348                                         case L1_SIGNAL_AIS_OFF:
2349                                         mISDNport->ais = 0;
2350                                         break;
2351                                         case L1_SIGNAL_RDI_ON:
2352                                         mISDNport->rdi = 1;
2353                                         break;
2354                                         case L1_SIGNAL_RDI_OFF:
2355                                         mISDNport->rdi = 0;
2356                                         break;
2357                                         case L1_SIGNAL_SLIP_TX:
2358                                         mISDNport->slip_tx++;
2359                                         break;
2360                                         case L1_SIGNAL_SLIP_RX:
2361                                         mISDNport->slip_rx++;
2362                                         break;
2363                                 }
2364                                 break;
2365
2366                                 case MT_L2ESTABLISH:
2367                                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2368                                 add_trace("tei", NULL, "%d", l3m->pid);
2369                                 end_trace();
2370                                 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2371                                 {
2372                                         if (mISDNport->l2establish)
2373                                         {
2374                                                 mISDNport->l2establish = 0;
2375                                                 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2376                                         }
2377                                         mISDNport->l2link = 1;
2378                                 }
2379                                 break;
2380
2381                                 case MT_L2RELEASE:
2382                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2383                                 add_trace("tei", NULL, "%d", l3m->pid);
2384                                 end_trace();
2385                                 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2386                                 {
2387                                         mISDNport->l2link = 0;
2388                                         if (mISDNport->l2hold)
2389                                         {
2390                                                 time(&mISDNport->l2establish);
2391                                                 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2392                                         }
2393                                 }
2394                                 break;
2395
2396                                 default:
2397                                 /* l3-data is sent to LCR */
2398                                 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2399                         }
2400                         /* free message */
2401                         free_l3_msg(l3m);
2402                 }
2403
2404 #if 0
2405                 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2406                 { ---}
2407                         PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2408                         mISDNport->l1timeout = 0;
2409 #endif
2410
2411                 /* layer 2 establish timer */
2412                 if (mISDNport->l2establish)
2413                 {
2414                         if (now-mISDNport->l2establish > 5)
2415                         {
2416                                 mISDNport->l2establish = 0;
2417                                 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2418                                 {
2419
2420                                         PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2421                                         mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2422                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2423                                         add_trace("tei", NULL, "%d", 0);
2424                                         end_trace();
2425                                         time(&mISDNport->l2establish);
2426                                         return(1);
2427                                 }
2428                         }
2429                 }
2430
2431
2432                 mISDNport = mISDNport->next;
2433         }
2434
2435         /* if we received at least one b-frame, we will return 1 */
2436         return(work);
2437 }
2438 #else
2439 int mISDN_handler(void)
2440 {
2441         int ret;
2442         struct mISDNport *mISDNport;
2443         class PmISDN *isdnport;
2444         int i;
2445         msg_t *msg;
2446         iframe_t *frm;
2447         msg_t *dmsg;
2448         mISDNuser_head_t *hh;
2449         net_stack_t *nst;
2450
2451         /* the que avoids loopbacks when replying to stack after receiving
2452          * from stack. */
2453         mISDNport = mISDNport_first;
2454         while(mISDNport)
2455         {
2456                 /* process turning on/off rx */
2457                 i = 0;
2458                 while(i < mISDNport->b_num)
2459                 {
2460                         /* process timer events for bchannel handling */
2461                         if (mISDNport->b_timer[i])
2462                         {
2463                                 if (mISDNport->b_timer[i] <= now_d)
2464                                         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2465                         }
2466                         isdnport=mISDNport->b_port[i];
2467                         if (isdnport)
2468                         {
2469                                 /* call bridges in user space OR crypto OR recording */
2470                                 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2471                                 {
2472                                         /* rx IS required */
2473                                         if (isdnport->p_m_rxoff)
2474                                         {
2475                                                 /* turn on RX */
2476                                                 isdnport->p_m_rxoff = 0;
2477                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
2478                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2479                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2480                                                 return(1);
2481                                         }
2482                                 } else
2483                                 {
2484                                         /* rx NOT required */
2485                                         if (!isdnport->p_m_rxoff)
2486                                         {
2487                                                 /* turn off RX */
2488                                                 isdnport->p_m_rxoff = 1;
2489                                                 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
2490                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2491                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2492                                                 return(1);
2493                                         }
2494                                 }
2495                                 /* recording */
2496                                 if (isdnport->p_record)
2497                                 {
2498                                         /* txdata IS required */
2499                                         if (!isdnport->p_m_txdata)
2500                                         {
2501                                                 /* turn on RX */
2502                                                 isdnport->p_m_txdata = 1;
2503                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
2504 #ifndef OLD_MISDN
2505                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2506                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2507 #endif
2508                                                 return(1);
2509                                         }
2510                                 } else
2511                                 {
2512                                         /* txdata NOT required */
2513                                         if (isdnport->p_m_txdata)
2514                                         {
2515                                                 /* turn off RX */
2516                                                 isdnport->p_m_txdata = 0;
2517                                                 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
2518 #ifndef OLD_MISDN
2519                                                 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2520                                                         ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2521 #endif
2522                                                 return(1);
2523                                         }
2524                                 }
2525                         }
2526                         i++;
2527                 }
2528 #if 0
2529                 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2530                 { ---}
2531                         PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2532                         mISDNport->l1timeout = 0;
2533 #endif
2534
2535                 if (mISDNport->l2establish)
2536                 {
2537                         if (now-mISDNport->l2establish > 5)
2538                         {
2539                                 mISDNport->l2establish = 0;
2540                                 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2541                                 {
2542                                         if (mISDNport->ntmode)
2543                                         {
2544                                                 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2545                                                 time(&mISDNport->l2establish);
2546                                                 /* establish */
2547                                                 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2548                                                 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2549                                                         free_msg(dmsg);
2550                                         } else {
2551                                                 iframe_t act;
2552
2553                                                 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2554                                                 time(&mISDNport->l2establish);
2555                                                 /* establish */
2556                                                 act.prim = DL_ESTABLISH | REQUEST; 
2557                                                 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2558                                                 act.dinfo = 0;
2559                                                 act.len = 0;
2560                                                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2561                                         }
2562                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2563                                         add_trace("tei", NULL, "%d", 0);
2564                                         end_trace();
2565                                         time(&mISDNport->l2establish);
2566                                         return(1);
2567                                 }
2568                         }
2569                 }
2570                 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2571                 {
2572                         if (mISDNport->ntmode)
2573                         {
2574                                 hh = (mISDNuser_head_t *)dmsg->data;
2575                                 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);
2576                                 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2577                                         free_msg(dmsg);
2578                         } else
2579                         {
2580                                 frm = (iframe_t *)dmsg->data;
2581                                 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2582                                 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2583                                 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);
2584                                 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2585                                 free_msg(dmsg);
2586                         }
2587                         return(1);
2588                 }
2589                 mISDNport = mISDNport->next;
2590         } 
2591
2592         /* no device, no read */
2593         if (mISDNdevice < 0)
2594                 return(0);
2595
2596         /* get message from kernel */
2597         if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2598                 return(1);
2599         ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2600         if (ret < 0)
2601         {
2602                 free_msg(msg);
2603                 if (errno == EAGAIN)
2604                         return(0);
2605                 FATAL("Failed to do mISDN_read()\n");
2606         }
2607         if (!ret)
2608         {
2609                 free_msg(msg);
2610 //              printf("%s: ERROR: mISDN_read() returns nothing\n");
2611                 return(0);
2612         }
2613         msg->len = ret;
2614         frm = (iframe_t *)msg->data;
2615
2616         /* global prim */
2617         switch(frm->prim)
2618         {
2619                 case MGR_DELLAYER | CONFIRM:
2620                 case MGR_INITTIMER | CONFIRM:
2621                 case MGR_ADDTIMER | CONFIRM:
2622                 case MGR_DELTIMER | CONFIRM:
2623                 case MGR_REMOVETIMER | CONFIRM:
2624                 free_msg(msg);
2625                 return(1);
2626         }
2627
2628         /* handle timer events from mISDN for NT-stack
2629          * note: they do not associate with a stack */
2630         if (frm->prim == (MGR_TIMER | INDICATION))
2631         {
2632                 itimer_t *it;
2633
2634                 /* find mISDNport */
2635                 mISDNport = mISDNport_first;
2636                 while(mISDNport)
2637                 {
2638                         /* nt mode only */
2639                         if (mISDNport->ntmode)
2640                         {
2641                                 it = mISDNport->nst.tlist;
2642                                 /* find timer */
2643                                 while(it)
2644                                 {
2645                                         if (it->id == (int)frm->addr)
2646                                                 break;
2647                                         it = it->next;
2648                                 }
2649                                 if (it)
2650                                         break;
2651                         }
2652                         mISDNport = mISDNport->next;
2653                 }
2654                 if (mISDNport)
2655                 {
2656                         mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2657                                 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2658
2659                         PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2660                         test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2661                         ret = it->function(it->data);
2662                 } else
2663                 {
2664                         PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2665                 }
2666                 goto out;
2667         }
2668
2669         /* find the mISDNport that belongs to the stack */
2670         mISDNport = mISDNport_first;
2671         while(mISDNport)
2672         {
2673                 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2674                         break;
2675                 mISDNport = mISDNport->next;
2676         } 
2677         if (!mISDNport)
2678         {
2679                 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2680                 // show a list of all mISDNports and their address
2681 #if 0
2682                 mISDNport = mISDNport_first;
2683                 while(mISDNport)
2684                 {
2685                         PERROR(" port %s  %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2686                         mISDNport = mISDNport->next;
2687                 } 
2688 #endif
2689                 goto out;
2690         }
2691
2692         /* master stack */
2693         if (!(frm->addr&FLG_CHILD_STACK))
2694         {
2695                 /* d-message */
2696                 switch(frm->prim)
2697                 {
2698                         case MGR_SHORTSTATUS | INDICATION:
2699                         case MGR_SHORTSTATUS | CONFIRM:
2700                         switch(frm->dinfo) {
2701                                 case SSTATUS_L1_ACTIVATED:
2702                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2703                                 end_trace();
2704                                 goto ss_act;
2705                                 case SSTATUS_L1_DEACTIVATED:
2706                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2707                                 end_trace();
2708                                 goto ss_deact;
2709                                 case SSTATUS_L2_ESTABLISHED:
2710                                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2711                                 end_trace();
2712                                 goto ss_estab;
2713                                 case SSTATUS_L2_RELEASED:
2714                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2715                                 end_trace();
2716                                 goto ss_rel;
2717                         }
2718                         break;
2719
2720                         case PH_ACTIVATE | CONFIRM:
2721                         case PH_ACTIVATE | INDICATION:
2722                         l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2723                         end_trace();
2724                         if (mISDNport->ntmode)
2725                         {
2726                                 mISDNport->l1link = 1;
2727                                 setup_queue(mISDNport, 1);
2728                                 goto l1_msg;
2729                         }
2730                         ss_act:
2731                         mISDNport->l1link = 1;
2732                         setup_queue(mISDNport, 1);
2733                         break;
2734
2735                         case PH_DEACTIVATE | CONFIRM:
2736                         case PH_DEACTIVATE | INDICATION:
2737                         l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2738                         end_trace();
2739                         if (mISDNport->ntmode)
2740                         {
2741                                 mISDNport->l1link = 0;
2742                                 setup_queue(mISDNport, 0);
2743                                 goto l1_msg;
2744                         }
2745                         ss_deact:
2746                         mISDNport->l1link = 0;
2747                         setup_queue(mISDNport, 0);
2748                         break;
2749
2750                         case PH_CONTROL | CONFIRM:
2751                         case PH_CONTROL | INDICATION:
2752                         PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2753                         break;
2754
2755                         case DL_ESTABLISH | INDICATION:
2756                         case DL_ESTABLISH | CONFIRM:
2757                         l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2758                         end_trace();
2759                         if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2760                         ss_estab:
2761                         if (!mISDNport->ntmode || mISDNport->ptp)
2762                         {
2763                                 if (mISDNport->l2establish)
2764                                 {
2765                                         mISDNport->l2establish = 0;
2766                                         PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2767                                 }
2768                                 mISDNport->l2link = 1;
2769                         }
2770                         break;
2771
2772                         case DL_RELEASE | INDICATION:
2773                         case DL_RELEASE | CONFIRM:
2774                         l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2775                         end_trace();
2776                         if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2777                         ss_rel:
2778                         if (!mISDNport->ntmode || mISDNport->ptp)
2779                         {
2780                                 mISDNport->l2link = 0;
2781                                 if (mISDNport->l2hold)
2782                                 {
2783                                         time(&mISDNport->l2establish);
2784                                         PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2785                                 }
2786                         }
2787                         break;
2788
2789                         default:
2790                         l1_msg:
2791                         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);
2792                         if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2793                         {
2794                                 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2795                         }
2796                         /* d-message */
2797                         if (mISDNport->ntmode)
2798                         {
2799                                 /* l1-data enters the nt-mode library */
2800                                 nst = &mISDNport->nst;
2801                                 if (nst->l1_l2(nst, msg))
2802                                         free_msg(msg);
2803                                 return(1);
2804                         } else
2805                         {
2806                                 /* l3-data is sent to pbx */
2807                                 if (stack2manager_te(mISDNport, msg))
2808                                         free_msg(msg);
2809                                 return(1);
2810                         }
2811                 }
2812         } else
2813         /* child stack */
2814         {
2815                 /* b-message */
2816                 switch(frm->prim)
2817                 {
2818                         /* we don't care about confirms, we use rx data to sync tx */
2819                         case PH_DATA | CONFIRM:
2820                         case DL_DATA | CONFIRM:
2821                         break;
2822
2823                         /* we receive audio data, we respond to it AND we send tones */
2824                         case PH_DATA | INDICATION:
2825                         case DL_DATA | INDICATION:
2826                         case PH_CONTROL | INDICATION:
2827                         case PH_SIGNAL | INDICATION:
2828                         i = 0;
2829                         while(i < mISDNport->b_num)
2830                         {
2831                                 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2832                                         break;
2833                                 i++;
2834                         }
2835                         if (i == mISDNport->b_num)
2836                         {
2837                                 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2838                                 break;
2839                         }
2840                         if (mISDNport->b_port[i])
2841                         {
2842 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2843                                 mISDNport->b_port[i]->bchannel_receive(frm);
2844                         } else
2845                                 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2846                         break;
2847
2848                         case PH_ACTIVATE | INDICATION:
2849                         case DL_ESTABLISH | INDICATION:
2850                         case PH_ACTIVATE | CONFIRM:
2851                         case DL_ESTABLISH | CONFIRM:
2852                         PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2853                         i = 0;
2854                         while(i < mISDNport->b_num)
2855                         {
2856                                 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2857                                         break;
2858                                 i++;
2859                         }
2860                         if (i == mISDNport->b_num)
2861                         {
2862                                 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2863                                 break;
2864                         }
2865                         bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2866                         break;
2867
2868                         case PH_DEACTIVATE | INDICATION:
2869                         case DL_RELEASE | INDICATION:
2870                         case PH_DEACTIVATE | CONFIRM:
2871                         case DL_RELEASE | CONFIRM:
2872                         PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2873                         i = 0;
2874                         while(i < mISDNport->b_num)
2875                         {
2876                                 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2877                                         break;
2878                                 i++;
2879                         }
2880                         if (i == mISDNport->b_num)
2881                         {
2882                                 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2883                                 break;
2884                         }
2885                         bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2886                         break;
2887
2888                         default:
2889                         PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2890                 }
2891         }
2892
2893         out:
2894         free_msg(msg);
2895         return(1);
2896 }
2897 #endif
2898
2899 #ifdef SOCKET_MISDN
2900 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2901 {
2902         /* IMPORTAINT:
2903          *
2904          * l3m must be queued, except for MT_ASSIGN
2905          *
2906          */
2907         struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2908         struct mbuffer *mb;
2909
2910         /* special MT_ASSIGN handling:
2911          *
2912          * if we request a PID from mlayer, we always do it while lcr is locked.
2913          * therefore we must check the MT_ASSIGN reply first before we lock.
2914          * this is because the MT_ASSIGN reply is received with the requesting
2915          * process, not by the mlayer thread!
2916          * this means, that the reply is sent during call of the request.
2917          * we must check if we get a reply and we know that we lcr is currently
2918          * locked.
2919          */
2920         if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2921         {
2922                 /* let's do some checking if someone changes stack behaviour */
2923                 if (mt_assign_pid != 0)
2924                         FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2925                 mt_assign_pid = pid;
2926                 return(0);
2927         }
2928         
2929         /* queue message, create, if required */
2930         if (!l3m)
2931         {
2932                 l3m = alloc_l3_msg();
2933                 if (!l3m)
2934                         FATAL("No memory for layer 3 message\n");
2935         }
2936         mb = container_of(l3m, struct mbuffer, l3);
2937         l3m->type = cmd;
2938         l3m->pid = pid;
2939         mqueue_tail(&mISDNport->upqueue, mb);
2940         return 0;
2941 }
2942
2943 #endif
2944
2945
2946 /*
2947  * global function to add a new card (port)
2948  */
2949 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2950 {
2951         int ret;
2952         struct mISDNport *mISDNport, **mISDNportp;
2953         int i, cnt;
2954         int pri, bri, pots;
2955         int nt, te;
2956 #ifdef SOCKET_MISDN
2957 //      struct mlayer3 *ml3;
2958         struct mISDN_devinfo devinfo;
2959         unsigned int protocol, prop;
2960
2961         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2962         if (ret < 0)
2963         {
2964                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2965                 return(NULL);
2966         }
2967 #else
2968         unsigned char buff[1025];
2969         iframe_t *frm = (iframe_t *)buff;
2970 //      interface_info_t ii;
2971         net_stack_t *nst;
2972         manager_t *mgr;
2973         layer_info_t li;
2974         stack_info_t *stinf;
2975
2976         /* query port's requirements */
2977         cnt = mISDN_get_stack_count(mISDNdevice);
2978 #endif
2979
2980         if (cnt <= 0)
2981         {
2982                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2983                 return(NULL);
2984         }
2985         if (port>cnt || port<1)
2986         {
2987                 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2988                 return(NULL);
2989         }
2990
2991         pri = bri = pots = nt = te = 0;
2992 #ifdef SOCKET_MISDN
2993         devinfo.id = port - 1;
2994         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2995         if (ret < 0)
2996         {
2997                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2998                 return(NULL);
2999         }
3000         /* output the port info */
3001         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3002         {
3003                 bri = 1;
3004                 te = 1;
3005         }
3006         if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3007         {
3008                 bri = 1;
3009                 nt = 1;
3010         }
3011         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3012         {
3013                 pri = 1;
3014                 te = 1;
3015         }
3016         if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3017         {
3018                 pri = 1;
3019                 nt = 1;
3020         }
3021 #ifdef ISDN_P_FXS
3022         if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3023         {
3024                 pots = 1;
3025                 te = 1;
3026         }
3027 #endif
3028 #ifdef ISDN_P_FXO
3029         if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3030         {
3031                 pots = 1;
3032                 nt = 1;
3033         }
3034 #endif
3035         if (force_nt && !nt)
3036         {
3037                 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
3038                 return(NULL);
3039         }
3040         if (bri && pri)
3041         {
3042                 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
3043                 return(NULL);
3044         }
3045         if (pots && !bri && !pri)
3046         {
3047                 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
3048                 return(NULL);
3049         }
3050         if (!bri && !pri)
3051         {
3052                 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
3053                 return(NULL);
3054         }
3055         if (!nt && !te)
3056         {
3057                 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
3058                 return(NULL);
3059         }
3060         /* set NT by turning off TE */
3061         if (force_nt && nt)
3062                 te = 0;
3063         /* if TE an NT is supported (and not forced to NT), turn off NT */
3064         if (te && nt)
3065                 nt = 0;
3066 #else
3067         ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
3068         if (ret < 0)
3069         {
3070                 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
3071                 return(NULL);
3072         }
3073         stinf = (stack_info_t *)&frm->data.p;
3074         switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3075         {
3076                 case ISDN_PID_L0_TE_S0:
3077                 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
3078                 break;
3079                 case ISDN_PID_L0_NT_S0:
3080                 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
3081                 nt = 1;
3082                 break;
3083                 case ISDN_PID_L0_TE_E1:
3084                 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1  interface line\n");
3085                 pri = 1;
3086                 break;
3087                 case ISDN_PID_L0_NT_E1:
3088                 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1  interface port\n");
3089                 pri = 1;
3090                 nt = 1;
3091                 break;
3092                 default:
3093                 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
3094                 return(NULL);
3095         }
3096         if (nt)
3097         {
3098                 /* NT */
3099                 if (stinf->pid.protocol[1] == 0)
3100                 {
3101                         PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
3102                         return(NULL);
3103                 }
3104                 if (stinf->pid.protocol[2])
3105                 {
3106                         PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
3107                         return(NULL);
3108                 }
3109         }
3110         if (te)
3111         {
3112                 /* TE */
3113                 if (stinf->pid.protocol[1] == 0)
3114                 {
3115                         PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
3116                         return(NULL);
3117                 }
3118                 if (stinf->pid.protocol[2] == 0)
3119                 {
3120                         PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
3121                         return(NULL);
3122                 }
3123                 if (stinf->pid.protocol[3] == 0)
3124                 {
3125                         PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
3126                         return(NULL);
3127                 } else
3128                 {
3129                         switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3130                         {
3131                                 case ISDN_PID_L3_DSS1USER:
3132                                 break;
3133
3134                                 default:
3135                                 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
3136                                 return(NULL);
3137                         }
3138                 }
3139                 if (stinf->pid.protocol[4])
3140                 {
3141                         PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3142                         return(NULL);
3143                 }
3144         }
3145 #endif
3146
3147         /* add mISDNport structure */
3148         mISDNportp = &mISDNport_first;
3149         while(*mISDNportp)
3150                 mISDNportp = &((*mISDNportp)->next);
3151         mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3152         pmemuse++;
3153         *mISDNportp = mISDNport;
3154
3155         /* if pri, must set PTP */
3156         if (pri)
3157                 ptp = 1;
3158         
3159         /* set l2hold */
3160         switch (l2hold)
3161         {
3162                 case -1: // off
3163                 l2hold = 0;
3164                 break;
3165                 case 1: // on
3166                 l2hold = 1;
3167                 break;
3168                 default:
3169                 if (ptp)
3170                         l2hold = 1;
3171                 else
3172                         l2hold = 0;
3173                 break;
3174         }
3175                 
3176         /* allocate ressources of port */
3177 #ifdef SOCKET_MISDN
3178         /* open layer 3 and init upqueue */
3179         protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
3180         prop = (1 << MISDN_FLG_L2_CLEAN);
3181         if (ptp) // ptp forced
3182                prop |= (1 << MISDN_FLG_PTP);
3183         if (nt) // supports hold/retrieve on nt-mode
3184                prop |= (1 << MISDN_FLG_NET_HOLD);
3185         if (l2hold) // supports layer 2 hold
3186                prop |= (1 << MISDN_FLG_L2_HOLD);
3187         /* queue must be initializes, because l3-thread may send messages during open_layer3() */
3188         mqueue_init(&mISDNport->upqueue);
3189         mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
3190         if (!mISDNport->ml3)
3191         {
3192                 mqueue_purge(&mISDNport->upqueue);
3193                 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
3194                 start_trace(port,
3195                         interface,
3196                         NULL,
3197                         NULL,
3198                         DIRECTION_NONE,
3199                         CATEGORY_CH,
3200                         0,
3201                         "PORT (open failed)");
3202                 end_trace();
3203                 mISDNport_close(mISDNport);
3204                 return(NULL);
3205         }
3206
3207 #if 0
3208         /* if ntmode, establish L1 to send the tei removal during start */
3209         if (mISDNport->ntmode)
3210         {
3211                 iframe_t act;
3212                 /* L1 */
3213                 act.prim = PH_ACTIVATE | REQUEST; 
3214                 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3215                 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3216                 act.dinfo = 0;
3217                 act.len = 0;
3218                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3219                 usleep(10000); /* to be sure, that l1 is up */
3220         }
3221 #endif
3222
3223         SCPY(mISDNport->name, devinfo.name);
3224         mISDNport->b_num = devinfo.nrbchan;
3225 #else
3226         msg_queue_init(&mISDNport->downqueue);
3227         mISDNport->d_stid = stinf->id;
3228         PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3229
3230         /* create layer intance */
3231         memset(&li, 0, sizeof(li));
3232         UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3233         li.object_id = -1;
3234         li.extentions = 0;
3235         li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3236         li.pid.layermask = ISDN_LAYER((nt?2:4));
3237         li.st = mISDNport->d_stid;
3238         ret = mISDN_new_layer(mISDNdevice, &li);
3239         if (ret)
3240         {
3241                 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3242                 closeport:
3243                 mISDNport_close(mISDNport);
3244                 return(NULL);
3245         }
3246         mISDNport->upper_id = li.id;
3247         ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3248         if (ret)
3249         {
3250                 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3251                 goto closeport;
3252         }
3253         mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3254         if (mISDNport->lower_id < 0)
3255         {
3256                 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3257                 goto closeport;
3258         }
3259         mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3260         if (mISDNport->upper_id < 0)
3261         {
3262                 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3263                 goto closeport;
3264         }
3265         PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3266
3267         /* if ntmode, establish L1 to send the tei removal during start */
3268         if (mISDNport->ntmode)
3269         {
3270                 iframe_t act;
3271                 /* L1 */
3272                 act.prim = PH_ACTIVATE | REQUEST; 
3273                 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3274                 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3275                 act.dinfo = 0;
3276                 act.len = 0;
3277                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3278                 usleep(10000); /* to be sure, that l1 is up */
3279         }
3280
3281         /* create nst (nt-mode only) */
3282         if (nt)
3283         {
3284                 mgr = &mISDNport->mgr;
3285                 nst = &mISDNport->nst;
3286
3287                 mgr->nst = nst;
3288                 nst->manager = mgr;
3289
3290                 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3291                 nst->device = mISDNdevice;
3292                 nst->cardnr = port;
3293                 nst->d_stid = mISDNport->d_stid;
3294
3295                 nst->feature = FEATURE_NET_HOLD;
3296                 if (ptp)
3297                         nst->feature |= FEATURE_NET_PTP;
3298                 if (pri)
3299                         nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3300 #if 0
3301                 i = 0;
3302                 while(i < mISDNport->b_num)
3303                 {
3304                         nst->b_stid[i] = mISDNport->b_stid[i];
3305                         i++;
3306                 }
3307 #endif
3308                 nst->l1_id = mISDNport->lower_id;
3309                 nst->l2_id = mISDNport->upper_id;
3310
3311                 /* phd */       
3312                 msg_queue_init(&nst->down_queue);
3313
3314                 Isdnl2Init(nst);
3315                 Isdnl3Init(nst);
3316         }
3317
3318         mISDNport->b_num = stinf->childcnt;
3319 #endif
3320         mISDNport->portnum = port;
3321         mISDNport->ntmode = nt;
3322         mISDNport->pri = pri;
3323         mISDNport->ptp = ptp;
3324         mISDNport->l2hold = l2hold;
3325         PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3326         i = 0;
3327         while(i < mISDNport->b_num)
3328         {
3329                 mISDNport->b_state[i] = B_STATE_IDLE;
3330 #ifdef SOCKET_MISDN
3331                 mISDNport->b_socket[i] = -1;
3332 #else
3333                 mISDNport->b_stid[i] = stinf->child[i];
3334                 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3335 #endif
3336                 i++;
3337         }
3338
3339 #ifdef SOCKET_MISDN
3340         /* if ptp, pull up the link */
3341         if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
3342         {
3343                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
3344                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3345                 add_trace("tei", NULL, "%d", 0);
3346                 end_trace();
3347                 time(&mISDNport->l2establish);
3348         }
3349 #else
3350         /* if te-mode, query state link */
3351         if (!mISDNport->ntmode)
3352         {
3353                 iframe_t act;
3354                 /* L2 */
3355                 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3356                 act.prim = MGR_SHORTSTATUS | REQUEST; 
3357                 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3358                 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3359                 act.len = 0;
3360                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3361         }
3362         /* if ptp AND te-mode, pull up the link */
3363         if (mISDNport->l2hold && !mISDNport->ntmode)
3364         {
3365                 iframe_t act;
3366                 /* L2 */
3367                 act.prim = DL_ESTABLISH | REQUEST; 
3368                 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3369                 act.dinfo = 0;
3370                 act.len = 0;
3371                 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3372
3373                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3374                 end_trace();
3375                 time(&mISDNport->l2establish);
3376         }
3377         /* if ptp AND nt-mode, pull up the link */
3378         if (mISDNport->l2hold && mISDNport->ntmode && mISDNport->ptp)
3379         {
3380                 msg_t *dmsg;
3381                 /* L2 */
3382                 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3383                 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3384                         free_msg(dmsg);
3385                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3386                 end_trace();
3387                 time(&mISDNport->l2establish);
3388         }
3389 #endif
3390
3391         /* initially, we assume that the link is down, exept for nt-ptmp */
3392         mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3393
3394         PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3395
3396         start_trace(mISDNport->portnum,
3397                     interface,
3398                     NULL,
3399                     NULL,
3400                     DIRECTION_NONE,
3401                     CATEGORY_CH,
3402                     0,
3403                     "PORT (open)");
3404         add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
3405         add_trace("channels", NULL, "%d", mISDNport->b_num);
3406         end_trace();
3407         return(mISDNport);
3408 }
3409
3410
3411 /*
3412  * function to free ALL cards (ports)
3413  */
3414 void mISDNport_close_all(void)
3415 {
3416         /* free all ports */
3417         while(mISDNport_first)
3418                 mISDNport_close(mISDNport_first);
3419 }
3420
3421 /*
3422  * free only one port
3423  */
3424 void mISDNport_close(struct mISDNport *mISDNport)
3425 {
3426         struct mISDNport **mISDNportp;
3427         class Port *port;
3428         class PmISDN *isdnport;
3429 #ifdef SOCKET_MISDN
3430 #else
3431         net_stack_t *nst;
3432         unsigned char buf[32];
3433 #endif
3434         int i;
3435
3436         /* remove all port instance that are linked to this mISDNport */
3437         port = port_first;
3438         while(port)
3439         {
3440                 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3441                 {
3442                         isdnport = (class PmISDN *)port;
3443                         if (isdnport->p_m_mISDNport)
3444                         {
3445                                 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3446                                 delete isdnport;
3447                         }
3448                 }
3449                 port = port->next;
3450         }
3451
3452         /* only if we are already part of interface */
3453         if (mISDNport->ifport)
3454         {
3455                 start_trace(mISDNport->portnum,
3456                             mISDNport->ifport->interface,
3457                             NULL,
3458                             NULL,
3459                             DIRECTION_NONE,
3460                             CATEGORY_CH,
3461                             0,
3462                             "PORT (close)");
3463                 end_trace();
3464         }
3465
3466         /* free bchannels */
3467         i = 0;
3468         while(i < mISDNport->b_num)
3469         {
3470 #ifdef SOCKET_MISDN
3471                 if (mISDNport->b_socket[i] > -1)
3472 #else
3473                 if (mISDNport->b_addr[i])
3474 #endif
3475                 {
3476                         _bchannel_destroy(mISDNport, i);
3477                         PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3478                 }
3479                 i++;
3480         }
3481
3482 #ifdef SOCKET_MISDN
3483         /* close layer 3, if open and purge upqueue */
3484         if (mISDNport->ml3)
3485         {
3486                 close_layer3(mISDNport->ml3);
3487                 mqueue_purge(&mISDNport->upqueue);
3488         }
3489 #else
3490         /* free ressources of port */
3491         msg_queue_purge(&mISDNport->downqueue);
3492
3493         /* free stacks */
3494         if (mISDNport->ntmode)
3495         {
3496                 nst = &mISDNport->nst;
3497                 if (nst->manager) /* to see if initialized */
3498                 {
3499                         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");
3500                         cleanup_Isdnl3(nst);
3501                         cleanup_Isdnl2(nst);
3502
3503                         /* phd */
3504                         msg_queue_purge(&nst->down_queue);
3505                         if (nst->phd_down_msg)
3506                                 FREE(nst->phd_down_msg, 0);
3507                 }
3508         }
3509
3510         PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3511         if (mISDNport->d_stid)
3512         {
3513                 if (mISDNport->upper_id)
3514                         mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3515         }
3516 #endif
3517
3518         /* remove from list */
3519         mISDNportp = &mISDNport_first;
3520         while(*mISDNportp)
3521         {
3522                 if (*mISDNportp == mISDNport)
3523                 {
3524                         *mISDNportp = (*mISDNportp)->next;
3525                         mISDNportp = NULL;
3526                         break;
3527                 }
3528                 mISDNportp = &((*mISDNportp)->next);
3529         }
3530
3531         if (mISDNportp)
3532                 FATAL("mISDNport not in list\n");
3533         
3534         FREE(mISDNport, sizeof(struct mISDNport));
3535         pmemuse--;
3536
3537 }
3538
3539
3540 /*
3541  * global function to show all available isdn ports
3542  */
3543 void mISDN_port_info(void)
3544 {
3545         int ret;
3546         int i, ii;
3547         int useable, nt, te, pri, bri, pots;
3548 #ifdef SOCKET_MISDN
3549         struct mISDN_devinfo devinfo;
3550         int sock;
3551
3552         /* open mISDN */
3553         sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3554         if (sock < 0)
3555         {
3556                 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3557                 exit(EXIT_FAILURE);
3558         }
3559
3560         /* get number of stacks */
3561         i = 1;
3562         ret = ioctl(sock, IMGETCOUNT, &ii);
3563         if (ret < 0)
3564         {
3565                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3566                 goto done;
3567         }
3568 #else
3569         int p;
3570         unsigned char buff[1025];
3571         iframe_t *frm = (iframe_t *)buff;
3572         stack_info_t *stinf;
3573         int device;
3574
3575         /* open mISDN */
3576         if ((device = mISDN_open()) < 0)
3577         {
3578                 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));
3579                 exit(EXIT_FAILURE);
3580         }
3581
3582         /* get number of stacks */
3583         i = 1;
3584         ii = mISDN_get_stack_count(device);
3585 #endif
3586         printf("\n");
3587         if (ii <= 0)
3588         {
3589                 printf("Found no card. Please be sure to load card drivers.\n");
3590                 goto done;
3591         }
3592
3593         /* loop the number of cards and get their info */
3594         while(i <= ii)
3595         {
3596                 nt = te = bri = pri = pots = 0;
3597                 useable = 0;
3598
3599 #ifdef SOCKET_MISDN
3600                 devinfo.id = i - 1;
3601                 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
3602                 if (ret < 0)
3603                 {
3604                         fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3605                         break;
3606                 }
3607
3608                 /* output the port info */
3609                 printf("Port %2d name='%s': ", i, devinfo.name);
3610                 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3611                 {
3612                         bri = 1;
3613                         te = 1;
3614                 }
3615                 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3616                 {
3617                         bri = 1;
3618                         nt = 1;
3619                 }
3620                 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3621                 {
3622                         pri = 1;
3623                         te = 1;
3624                 }
3625                 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3626                 {
3627                         pri = 1;
3628                         nt = 1;
3629                 }
3630 #ifdef ISDN_P_FXS
3631                 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3632                 {
3633                         pots = 1;
3634                         te = 1;
3635                 }
3636 #endif
3637 #ifdef ISDN_P_FXO
3638                 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3639                 {
3640                         pots = 1;
3641                         nt = 1;
3642                 }
3643 #endif
3644                 if ((te || nt) && (bri || pri || pots))
3645                         useable = 1;
3646
3647                 if (te && nt && bri)
3648                         printf("TE/NT-mode BRI S/T (for phone lines & phones)");
3649                 if (te && !nt && bri)
3650                         printf("TE-mode    BRI S/T (for phone lines)");
3651                 if (nt && !te && bri)
3652                         printf("NT-mode    BRI S/T (for phones)");
3653                 if (te && nt && pri)
3654                         printf("TE/NT-mode PRI E1  (for phone lines & E1 devices)");
3655                 if (te && !nt && pri)
3656                         printf("TE-mode    PRI E1  (for phone lines)");
3657                 if (nt && !te && pri)
3658                         printf("NT-mode    PRI E1  (for E1 devices)");
3659                 if (te && nt && pots)
3660                         printf("FXS/FXO    POTS    (for analog lines & phones)");
3661                 if (te && !nt && pots)
3662                         printf("FXS        POTS    (for analog lines)");
3663                 if (nt && !te && pots)
3664                         printf("FXO        POTS    (for analog phones)");
3665                 if (pots)
3666                 {
3667                         useable = 0;
3668                         printf("\n -> Analog interfaces are not supported.");
3669                 } else
3670                 if (!useable)
3671                 {
3672                         printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3673                 }
3674                 printf("\n");
3675
3676                 printf("  - %d B-channels\n", devinfo.nrbchan);
3677 #else
3678                 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3679                 if (ret <= 0)
3680                 {
3681                         fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3682                         break;
3683                 }
3684                 stinf = (stack_info_t *)&frm->data.p;
3685
3686                 /* output the port info */
3687                 printf("Port %2d: ", i);
3688                 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3689                 {
3690                         case ISDN_PID_L0_TE_S0:
3691                         useable = 1;
3692                         te = 1;
3693                         bri = 1;
3694                         printf("TE-mode BRI S/T interface line (for phone lines)");
3695                         break;
3696                         case ISDN_PID_L0_NT_S0:
3697                         useable = 1;
3698                         nt = 1;
3699                         bri = 1;
3700                         printf("NT-mode BRI S/T interface port (for phones)");
3701                         break;
3702                         case ISDN_PID_L0_TE_E1:
3703                         useable = 1;
3704                         te = 1;
3705                         pri = 1;
3706                         printf("TE-mode PRI E1  interface line (for phone lines)");
3707                         break;
3708                         case ISDN_PID_L0_NT_E1:
3709                         useable = 1;
3710                         nt = 1;
3711                         pri = 1;
3712                         printf("NT-mode PRI E1  interface port (for E1 devices)");
3713                         break;
3714                         default:
3715                         useable = 0;
3716                         printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3717                 }
3718                 printf("\n");
3719
3720                 if (nt)
3721                 {
3722                         if (stinf->pid.protocol[1] == 0)
3723                         {
3724                                 useable = 0;
3725                                 printf(" -> Missing layer 1 NT-mode protocol.\n");
3726                         }
3727                         p = 2;
3728                         while(p <= MAX_LAYER_NR) {
3729                                 if (stinf->pid.protocol[p])
3730                                 {
3731                                         useable = 0;
3732                                         printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3733                                 }
3734                                 p++;
3735                         }
3736                         if (useable)
3737                         {
3738                                 if (pri)
3739                                         printf(" -> Interface is Point-To-Point (PRI).\n");
3740                                 else
3741                                         printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3742                         }
3743                 }
3744                 if (te)
3745                 {
3746                         if (stinf->pid.protocol[1] == 0)
3747                         {
3748                                 useable = 0;
3749                                 printf(" -> Missing layer 1 protocol.\n");
3750                         }
3751                         if (stinf->pid.protocol[2] == 0)
3752                         {
3753                                 useable = 0;
3754                                 printf(" -> Missing layer 2 protocol.\n");
3755                         }
3756                         if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3757                         {
3758                                 printf(" -> Interface is Poin-To-Point.\n");
3759                         }
3760                         if (stinf->pid.protocol[3] == 0)
3761                         {
3762                                 useable = 0;
3763                                 printf(" -> Missing layer 3 protocol.\n");
3764                         } else
3765                         {
3766                                 printf(" -> Protocol: ");
3767                                 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3768                                 {
3769                                         case ISDN_PID_L3_DSS1USER:
3770                                         printf("DSS1 (Euro ISDN)");
3771                                         break;
3772
3773                                         default:
3774                                         useable = 0;
3775                                         printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3776                                 }
3777                                 printf("\n");
3778                         }
3779                         p = 4;
3780                         while(p <= MAX_LAYER_NR) {
3781                                 if (stinf->pid.protocol[p])
3782                                 {
3783                                         useable = 0;
3784                                         printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3785                                 }
3786                                 p++;
3787                         }
3788                 }
3789                 printf("  - %d B-channels\n", stinf->childcnt);
3790 #endif
3791
3792                 if (!useable)
3793                         printf(" * Port NOT useable for LCR\n");
3794
3795                 printf("--------\n");
3796
3797                 i++;
3798         }
3799         printf("\n");
3800
3801 done:
3802 #ifdef SOCKET_MISDN
3803         close(sock);
3804 #else
3805         /* close mISDN */
3806         if ((ret = mISDN_close(device)))
3807                 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3808 #endif
3809 }
3810
3811
3812 /*
3813  * enque data from upper buffer
3814  */
3815 void PmISDN::txfromup(unsigned char *data, int length)
3816 {
3817 #ifdef SOCKET_MISDN
3818         unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3819         struct mISDNhead *hh = (struct mISDNhead *)buf;
3820         int ret;
3821
3822         if (p_m_b_index < 0)
3823                 return;
3824         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
3825                 return;
3826 #else
3827         unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3828         iframe_t *frm = (iframe_t *)buf;
3829
3830         if (p_m_b_index < 0)
3831                 return;
3832         if (!p_m_mISDNport->b_addr[p_m_b_index])
3833                 return;
3834 #endif
3835
3836         /* check if high priority tones exist
3837          * ignore data in this case
3838          */
3839         if (p_tone_name[0] || p_m_crypt_msg_loops)
3840                 return;
3841
3842         /* preload procedure
3843          * if transmit buffer in DSP module is empty,
3844          * preload it to DSP_LOAD to prevent jitter gaps.
3845          */
3846         if (p_m_load==0 && ISDN_LOAD>0)
3847         {
3848 #ifdef SOCKET_MISDN
3849                 hh->prim = PH_DATA_REQ; 
3850                 hh->id = 0;
3851                 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3852                 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
3853                 if (ret <= 0)
3854                         PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3855 #else
3856                 frm->prim = DL_DATA | REQUEST; 
3857                 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3858                 frm->dinfo = 0;
3859                 frm->len = ISDN_LOAD;
3860                 memset(buf+mISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3861                 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+ISDN_LOAD, TIMEOUT_1SEC);
3862 #endif
3863                 p_m_load += ISDN_LOAD;
3864         }
3865
3866         /* drop if load would exceed ISDN_MAXLOAD
3867          * this keeps the delay not too high
3868          */
3869         if (p_m_load+length > ISDN_MAXLOAD)
3870                 return;
3871
3872         /* make and send frame */
3873 #ifdef SOCKET_MISDN
3874         hh->prim = PH_DATA_REQ;
3875         hh->id = 0;
3876         memcpy(buf+MISDN_HEADER_LEN, data, length);
3877         ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3878         if (ret <= 0)
3879                 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3880 #else
3881         frm->prim = DL_DATA | REQUEST; 
3882         frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3883         frm->dinfo = 0;
3884         frm->len = length;
3885         memcpy(buf+mISDN_HEADER_LEN, data, length);
3886         mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3887 #endif
3888         p_m_load += length;
3889 }
3890