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