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