7be3d4fc026eda402aec16df16c08721f95546f5
[lcr.git] / mISDN.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN port abstraction for dss1                                           **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13 #include "myisdn.h"
14
15 extern "C" {
16 #define MISDN_OLD_AF_COMPATIBILITY 1
17 #include <compat_af_isdn.h>
18 }
19 #include <q931.h>
20
21 #undef offsetof
22 #ifdef __compiler_offsetof
23 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
24 #else
25 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
26 #endif
27
28 #ifndef container_of
29 #define container_of(ptr, type, member) ({                      \
30         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
31         (type *)( (char *)__mptr - offsetof(type,member) );})
32 #endif
33
34 // timeouts if activating/deactivating response from mISDN got lost
35 #define B_TIMER_ACTIVATING 1 // seconds
36 #define B_TIMER_DEACTIVATING 1 // seconds
37
38 /* list of mISDN ports */
39 struct mISDNport *mISDNport_first;
40
41 /* noise randomizer */
42 unsigned char mISDN_rand[256];
43 int mISDN_rand_count = 0;
44
45 unsigned int mt_assign_pid = ~0;
46
47 int mISDNsocket = -1;
48 static int upqueue_pipe[2];
49 static struct lcr_fd upqueue_fd;
50 int upqueue_avail = 0;
51
52 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
53 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
54
55 int mISDN_initialize(void)
56 {
57         char filename[256];
58
59         init_af_isdn();
60
61         /* try to open raw socket to check kernel */
62         mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
63         if (mISDNsocket < 0) {
64                 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
65                 return(-1);
66         }
67
68         /* init mlayer3 */
69         init_layer3(4); // buffer of 4
70
71         /* open debug, if enabled and not only stack debugging */
72         if (options.deb) {
73                 SPRINT(filename, "%s/debug.log", LOG_DIR);
74                 debug_fp = fopen(filename, "a");
75         }
76
77         if (options.deb & DEBUG_STACK) {
78                 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
79                 mISDN_debug_init(0xfffffeff, filename, filename, filename);
80         } else
81                 mISDN_debug_init(0, NULL, NULL, NULL);
82
83         if (pipe(upqueue_pipe) < 0)
84                 FATAL("Failed to open pipe\n");
85         memset(&upqueue_fd, 0, sizeof(upqueue_fd));
86         upqueue_fd.fd = upqueue_pipe[0];
87         register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
88
89         return(0);
90 }
91
92 void mISDN_deinitialize(void)
93 {
94         cleanup_layer3();
95
96         mISDN_debug_close();
97
98         if (debug_fp)
99                 fclose(debug_fp);
100         debug_fp = NULL;
101
102         if (mISDNsocket > -1)
103                 close(mISDNsocket);
104
105         if (upqueue_fd.inuse) {
106                 unregister_fd(&upqueue_fd);
107                 close(upqueue_pipe[0]);
108                 close(upqueue_pipe[1]);
109         }
110         upqueue_avail = 0;
111 }
112
113 int load_timer(struct lcr_timer *timer, void *instance, int index);
114
115 /*
116  * constructor
117  */
118 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
119 {
120         p_m_mISDNport = mISDNport;
121         p_m_portnum = mISDNport->portnum;
122         p_m_b_index = -1;
123         p_m_b_channel = 0;
124         p_m_b_exclusive = 0;
125         p_m_b_reserve = 0;
126         p_m_b_mode = mode;
127         p_m_hold = 0;
128         p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
129         p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
130         p_m_conf = 0;
131         p_m_mute = 0;
132         p_m_txdata = 0;
133         p_m_delay = 0;
134         p_m_echo = 0;
135         p_m_tone = 0;
136         p_m_rxoff = 0;
137         p_m_joindata = 0;
138         p_m_inband_send_on = 0;
139         p_m_inband_receive_on = 0;
140         p_m_dtmf = !mISDNport->ifport->nodtmf;
141         memset(&p_m_timeout, 0, sizeof(p_m_timeout));
142         add_timer(&p_m_timeout, mISDN_timeout, this, 0);
143         p_m_remote_ref = 0; /* channel shall be exported to given remote */
144         p_m_remote_id = 0; /* remote admin socket */
145         SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
146         
147         /* audio */
148         memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
149         add_timer(&p_m_loadtimer, load_timer, this, 0);
150         p_m_load = 0;
151         p_m_last_tv_sec = 0;
152
153         /* crypt */
154         p_m_crypt = 0;
155         p_m_crypt_listen = 0;
156         p_m_crypt_msg_loops = 0;
157         p_m_crypt_msg_loops = 0;
158         p_m_crypt_msg_len = 0;
159         p_m_crypt_msg[0] = '\0';
160         p_m_crypt_msg_current = 0;
161         p_m_crypt_key_len = 0;
162         p_m_crypt_listen = 0;
163         p_m_crypt_listen_state = 0;
164         p_m_crypt_listen_len = 0;
165         p_m_crypt_listen_msg[0] = '\0';
166         p_m_crypt_listen_crc = 0;
167         if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
168                 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
169                 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
170                 p_m_crypt = 1;
171         }
172
173         /* if any channel requested by constructor */
174         if (channel == CHANNEL_ANY) {
175                 /* reserve channel */
176                 p_m_b_reserve = 1;
177                 mISDNport->b_reserved++;
178         }
179
180         /* reserve channel */
181         if (channel > 0) // only if constructor was called with a channel resevation
182                 seize_bchannel(channel, exclusive);
183
184         /* we increase the number of objects: */
185         mISDNport->use++;
186         PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
187 //inband_receive_on();
188 }
189
190
191 /*
192  * destructor
193  */
194 PmISDN::~PmISDN()
195 {
196         struct lcr_msg *message;
197
198         del_timer(&p_m_timeout);
199         del_timer(&p_m_loadtimer);
200
201         /* remove bchannel relation */
202         drop_bchannel();
203
204         /* release epoint */
205         while (p_epointlist) {
206                 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
207                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
208                 message->param.disconnectinfo.cause = 16;
209                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
210                 message_put(message);
211                 /* remove from list */
212                 free_epointlist(p_epointlist);
213         }
214
215         /* we decrease the number of objects: */
216         p_m_mISDNport->use--;
217         PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
218 }
219
220
221 /*
222  * trace
223  */
224 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
225 {
226         /* init trace with given values */
227         start_trace(mISDNport?mISDNport->portnum:-1,
228                     (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
229                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
230                     port?port->p_dialinginfo.id:NULL,
231                     direction,
232                     CATEGORY_CH,
233                     port?port->p_serial:0,
234                     msgtext);
235 }
236
237
238 /*
239  * layer trace header
240  */
241 static struct isdn_message {
242         const char *name;
243         unsigned int value;
244 } isdn_message[] = {
245         {"PH_ACTIVATE", L1_ACTIVATE_REQ},
246         {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
247         {"DL_ESTABLISH", L2_ESTABLISH_REQ},
248         {"DL_RELEASE", L2_RELEASE_REQ},
249         {"UNKNOWN", L3_UNKNOWN_REQ},
250         {"MT_TIMEOUT", L3_TIMEOUT_REQ},
251         {"MT_SETUP", L3_SETUP_REQ},
252         {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
253         {"MT_PROCEEDING", L3_PROCEEDING_REQ},
254         {"MT_ALERTING", L3_ALERTING_REQ},
255         {"MT_CONNECT", L3_CONNECT_REQ},
256         {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
257         {"MT_DISCONNECT", L3_DISCONNECT_REQ},
258         {"MT_RELEASE", L3_RELEASE_REQ},
259         {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
260         {"MT_INFORMATION", L3_INFORMATION_REQ},
261         {"MT_PROGRESS", L3_PROGRESS_REQ},
262         {"MT_NOTIFY", L3_NOTIFY_REQ},
263         {"MT_SUSPEND", L3_SUSPEND_REQ},
264         {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
265         {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
266         {"MT_RESUME", L3_RESUME_REQ},
267         {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
268         {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
269         {"MT_HOLD", L3_HOLD_REQ},
270         {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
271         {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
272         {"MT_RETRIEVE", L3_RETRIEVE_REQ},
273         {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
274         {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
275         {"MT_FACILITY", L3_FACILITY_REQ},
276         {"MT_STATUS", L3_STATUS_REQ},
277         {"MT_RESTART", L3_RESTART_REQ},
278         {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
279         {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
280         {NULL, 0},
281 };
282 static const char *isdn_prim[4] = {
283         " REQUEST",
284         " CONFIRM",
285         " INDICATION",
286         " RESPONSE",
287 };
288 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
289 {
290         int i;
291         char msgtext[64];
292
293         SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
294         /* select message and primitive text */
295         i = 0;
296         while(isdn_message[i].name) {
297 //              if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
298                 if (isdn_message[i].value == (msg&0xffffff00)) {
299                         SCPY(msgtext, isdn_message[i].name);
300                         break;
301                 }
302                 i++;
303         }
304         SCAT(msgtext, isdn_prim[msg&0x00000003]);
305
306         /* add direction */
307         if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
308                 if (mISDNport) {
309                         if (mISDNport->ntmode) {
310                                 if (direction == DIRECTION_OUT)
311                                         SCAT(msgtext, " N->U");
312                                 else
313                                         SCAT(msgtext, " N<-U");
314                         } else {
315                                 if (direction == DIRECTION_OUT)
316                                         SCAT(msgtext, " U->N");
317                                 else
318                                         SCAT(msgtext, " U<-N");
319                         }
320                 }
321         }
322
323         /* init trace with given values */
324         start_trace(mISDNport?mISDNport->portnum:-1,
325                     mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
326                     port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
327                     port?port->p_dialinginfo.id:NULL,
328                     direction,
329                     CATEGORY_CH,
330                     port?port->p_serial:0,
331                     msgtext);
332 }
333
334
335 /*
336  * send control information to the channel (dsp-module)
337  */
338 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
339 {
340         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
341         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
342         unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
343         int ret;
344
345         if (sock < 0)
346                 return;
347
348         ctrl->prim = PH_CONTROL_REQ;
349         ctrl->id = 0;
350         *d++ = c1;
351         *d++ = c2;
352         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
353         if (ret <= 0)
354                 PERROR("Failed to send to socket %d\n", sock);
355         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
356         if (c1 == DSP_CONF_JOIN)
357                 add_trace(trace_name, NULL, "0x%08x", trace_value);
358         else
359                 add_trace(trace_name, NULL, "%d", trace_value);
360         end_trace();
361 }
362
363 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, const char *trace_name, int trace_value)
364 {
365         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
366         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
367         unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
368         int ret;
369
370         if (sock < 0)
371                 return;
372
373         ctrl->prim = PH_CONTROL_REQ;
374         ctrl->id = 0;
375         *d++ = c1;
376         memcpy(d, c2, c2_len);
377         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
378         if (ret <= 0)
379                 PERROR("Failed to send to socket %d\n", sock);
380         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
381         add_trace(trace_name, NULL, "%d", trace_value);
382         end_trace();
383 }
384
385 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
386
387 /*
388  * subfunction for bchannel_event
389  * create stack
390  */
391 static int _bchannel_create(struct mISDNport *mISDNport, int i)
392 {
393         int ret;
394         struct sockaddr_mISDN addr;
395
396         if (mISDNport->b_sock[i].inuse) {
397                 PERROR("Error: Socket already created for index %d\n", i);
398                 return(0);
399         }
400
401         /* open socket */
402 //#warning testing without DSP
403 //      mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
404         mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
405         if (mISDNport->b_sock[i].fd < 0) {
406                 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
407                 return(0);
408         }
409
410         /* register callback for read */
411         register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
412         
413         /* bind socket to bchannel */
414         addr.family = AF_ISDN;
415         addr.dev = mISDNport->portnum;
416         addr.channel = i+1+(i>=15);
417         ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
418         if (ret < 0) {
419                 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer (errno=%d). Did you load mISDN_dsp.ko?\n", i, errno);
420                 close(mISDNport->b_sock[i].fd);
421                 unregister_fd(&mISDNport->b_sock[i]);
422                 return(0);
423         }
424
425         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
426         add_trace("channel", NULL, "%d", i+1+(i>=15));
427         add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
428         end_trace();
429
430         return(1);
431 }
432
433
434 /*
435  * subfunction for bchannel_event
436  * activate / deactivate request
437  */
438 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
439 {
440         struct mISDNhead act;
441         int ret;
442
443         if (!mISDNport->b_sock[i].inuse)
444                 return;
445         act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ; 
446         act.id = 0;
447         ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
448         if (ret <= 0)
449                 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
450
451         /* trace */
452         chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
453         add_trace("channel", NULL, "%d", i+1+(i>=15));
454         if (timeout)
455                 add_trace("event", NULL, "timeout recovery");
456         end_trace();
457 }
458
459
460 /*
461  * subfunction for bchannel_event
462  * set features
463  */
464 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
465 {
466         struct PmISDN *port;
467         int handle, mode;
468
469         if (!mISDNport->b_sock[i].inuse)
470                 return;
471         handle = mISDNport->b_sock[i].fd;
472         port = mISDNport->b_port[i];
473         mode = mISDNport->b_mode[i];
474         if (!port) {
475                 PERROR("bchannel index i=%d not associated with a port object\n", i);
476                 return;
477         }
478
479         /* set dsp features */
480         if (port->p_m_txdata)
481                 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
482         if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
483                 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
484         if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
485                 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
486         if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
487                 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
488         if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
489                 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
490         if (port->p_m_conf && !port->p_m_mute)
491                 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
492         if (port->p_m_echo)
493                 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
494         if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
495                 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
496         if (port->p_m_rxoff)
497                 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
498 //      if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
499 //              ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
500         if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
501                 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
502         if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
503                 ph_control_block(mISDNport, port, handle, DSP_BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
504 }
505
506
507 void PmISDN::set_conf(int oldconf, int newconf)
508 {
509                 if (oldconf != newconf) {
510                         PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
511                         if (p_m_b_index > -1)
512                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
513                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, (newconf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, newconf, "DSP-CONF", newconf);
514                 } else
515                         PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
516 }
517
518
519 /*
520  * subfunction for bchannel_event
521  * destroy stack
522  */
523 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
524 {
525         if (!mISDNport->b_sock[i].inuse)
526                 return;
527         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
528         add_trace("channel", NULL, "%d", i+1+(i>=15));
529         add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
530         end_trace();
531         close(mISDNport->b_sock[i].fd);
532         unregister_fd(&mISDNport->b_sock[i]);
533 }
534
535
536 /*
537 bchannel procedure
538 ------------------
539
540 A bchannel goes through the following states in this order:
541
542 - B_STATE_IDLE
543 No one is using the bchannel.
544 It is available and not linked to Port class, nor reserved.
545
546 - B_STATE_ACTIVATING
547 The bchannel stack is created and an activation request is sent.
548 It MAY be linked to Port class, but already unlinked due to Port class removal.
549
550 - B_STATE_ACTIVE
551 The bchannel is active and cofigured to the Port class needs.
552 Also it is linked to a Port class, otherwhise it would be deactivated.
553
554 - B_STATE_DEACTIVATING
555 The bchannel is in deactivating state, due to deactivation request.
556 It may be linked to a Port class, that likes to reactivate it.
557
558 - B_STATE_IDLE
559 See above.
560 After deactivating bchannel, and if not used, the bchannel becomes idle again.
561
562 Also the bchannel may be exported, but only if the state is or becomes idle:
563
564 - B_STATE_EXPORTING
565 The bchannel assignment has been sent to the remove application.
566
567 - B_STATE_REMOTE
568 The bchannel assignment is acknowledged by the remote application.
569
570 - B_STATE_IMPORTING
571 The bchannel is re-imported by mISDN port object.
572
573 - B_STATE_IDLE
574 See above.
575 After re-importing bchannel, and if not used, the bchannel becomes idle again.
576
577
578 A bchannel can have the following events:
579
580 - B_EVENT_USE
581 A bchannel is required by a Port class.
582
583 - B_EVENT_ACTIVATED
584 The bchannel beomes active.
585
586 - B_EVENT_DROP
587 The bchannel is not required by Port class anymore
588
589 - B_EVENT_DEACTIVATED
590 The bchannel becomes inactive.
591
592 - B_EVENT_EXPORTED
593 The bchannel is now used by remote application.
594
595 - B_EVENT_IMPORTED
596 The bchannel is not used by remote application.
597
598 - B_EVENT_EXPORTREQUEST
599 The bchannel shall be exported to the remote application.
600
601 - B_EVENT_IMPORTREQUEST
602 The bchannel is released from the remote application.
603
604 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
605
606 if an export request is receive by remote application, p_m_remote_* is set.
607 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.)
608 - set on export request from remote application (if port is assigned)
609 - set on channel use, if requested by remote application (p_m_remote_*)
610 - cleared on drop request
611
612 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
613 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
614 the bchannel import/export is acknowledged with stack given.
615
616 if exporting, b_remote_*[index] is set to the remote socket id.
617 if importing has been acknowledged. b_remote_*[index] is cleared.
618
619 */
620
621 /*
622  * process bchannel events
623  * - mISDNport is a pointer to the port's structure
624  * - i is the index of the bchannel
625  * - event is the B_EVENT_* value
626  * - port is the PmISDN class pointer
627  */
628 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
629 {
630         class PmISDN *b_port = mISDNport->b_port[i];
631         int state = mISDNport->b_state[i];
632         int timer = -1; // no change
633         unsigned int p_m_remote_ref = 0;
634         unsigned int p_m_remote_id = 0;
635         int p_m_tx_gain = 0;
636         int p_m_rx_gain = 0;
637         char *p_m_pipeline = NULL;
638         unsigned char *p_m_crypt_key = NULL;
639         int p_m_crypt_key_len = 0;
640         int p_m_crypt_key_type = 0;
641         unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
642
643         if (b_port) {
644                 p_m_remote_id = b_port->p_m_remote_id;
645                 p_m_remote_ref = b_port->p_m_remote_ref;
646                 p_m_tx_gain = b_port->p_m_tx_gain;
647                 p_m_rx_gain = b_port->p_m_rx_gain;
648                 p_m_pipeline = b_port->p_m_pipeline;
649                 p_m_crypt_key = b_port->p_m_crypt_key;
650                 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
651                 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
652         }
653
654         switch(event) {
655                 case B_EVENT_USE:
656                 /* port must be linked in order to allow activation */
657                 if (!b_port)
658                         FATAL("bchannel must be linked to a Port class\n");
659                 switch(state) {
660                         case B_STATE_IDLE:
661                         if (p_m_remote_ref) {
662                                 /* export bchannel */
663                                 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
664                                 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
665                                 add_trace("type", NULL, "assign");
666                                 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
667                                 end_trace();
668                                 state = B_STATE_EXPORTING;
669                                 mISDNport->b_remote_id[i] = p_m_remote_id;
670                                 mISDNport->b_remote_ref[i] = p_m_remote_ref;
671                         } else {
672                                 /* create stack and send activation request */
673                                 if (_bchannel_create(mISDNport, i)) {
674                                         _bchannel_activate(mISDNport, i, 1, 0);
675                                         state = B_STATE_ACTIVATING;
676                                         timer = B_TIMER_ACTIVATING;
677                                 }
678                         }
679                         break;
680
681                         case B_STATE_ACTIVATING:
682                         case B_STATE_EXPORTING:
683                         /* do nothing, because it is already activating */
684                         break;
685
686                         case B_STATE_DEACTIVATING:
687                         case B_STATE_IMPORTING:
688                         /* do nothing, because we must wait until we can reactivate */
689                         break;
690
691                         default:
692                         /* problems that might ocurr:
693                          * B_EVENT_USE is received when channel already in use.
694                          * bchannel exported, but not freed by other port
695                          */
696                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
697                 }
698                 break;
699
700                 case B_EVENT_EXPORTREQUEST:
701                 /* special case where the bchannel is requested by remote */
702                 if (!p_m_remote_ref) {
703                         PERROR("export request without remote channel set, please correct.\n");
704                         break;
705                 }
706                 switch(state) {
707                         case B_STATE_IDLE:
708                         /* in case, the bchannel is exported right after seize_bchannel */
709                         /* export bchannel */
710                         /* p_m_remote_id is set, when this event happens. */
711                         message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
712                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
713                         add_trace("type", NULL, "assign");
714                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
715                         end_trace();
716                         state = B_STATE_EXPORTING;
717                         mISDNport->b_remote_id[i] = p_m_remote_id;
718                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
719                         break;
720
721                         case B_STATE_ACTIVATING:
722                         case B_STATE_EXPORTING:
723                         /* do nothing, because it is already activating */
724                         break;
725
726                         case B_STATE_DEACTIVATING:
727                         case B_STATE_IMPORTING:
728                         /* do nothing, because we must wait until we can reactivate */
729                         break;
730
731                         case B_STATE_ACTIVE:
732                         /* bchannel is active, so we deactivate */
733                         _bchannel_activate(mISDNport, i, 0, 0);
734                         state = B_STATE_DEACTIVATING;
735                         timer = B_TIMER_DEACTIVATING;
736                         break;
737
738                         default:
739                         /* problems that might ocurr:
740                          * ... when channel already in use.
741                          * bchannel exported, but not freed by other port
742                          */
743                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
744                 }
745                 break;
746
747                 case B_EVENT_IMPORTREQUEST:
748                 /* special case where the bchannel is released by remote */
749                 if (p_m_remote_ref) {
750                         PERROR("import request with remote channel set, please correct.\n");
751                         break;
752                 }
753                 switch(state) {
754                         case B_STATE_IDLE:
755                         case B_STATE_ACTIVE:
756                         /* bchannel is not exported */
757                         break;
758
759                         case B_STATE_ACTIVATING:
760                         case B_STATE_EXPORTING:
761                         /* do nothing because we must wait until bchanenl is active before deactivating */
762                         break;
763
764                         case B_STATE_REMOTE:
765                         /* bchannel is exported, so we re-import */
766                         message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
767                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
768                         add_trace("type", NULL, "remove");
769                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
770                         end_trace();
771                         state = B_STATE_IMPORTING;
772                         break;
773
774                         case B_STATE_DEACTIVATING:
775                         case B_STATE_IMPORTING:
776                         /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
777                         break;
778
779                         default:
780                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
781                 }
782                 break;
783
784                 case B_EVENT_ACTIVATED:
785                 timer = 0;
786                 switch(state) {
787                         case B_STATE_ACTIVATING:
788                         if (b_port && !p_m_remote_id) {
789                                 /* bchannel is active and used by Port class, so we configure bchannel */
790                                 _bchannel_configure(mISDNport, i);
791                                 state = B_STATE_ACTIVE;
792                                 b_port->p_m_load = 0;
793                         } else {
794                                 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
795                                 _bchannel_activate(mISDNport, i, 0, 0);
796                                 state = B_STATE_DEACTIVATING;
797                                 timer = B_TIMER_DEACTIVATING;
798                         }
799                         break;
800
801                         default:
802                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
803                 }
804                 break;
805
806                 case B_EVENT_EXPORTED:
807                 switch(state) {
808                         case B_STATE_EXPORTING:
809                         if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
810                                 /* remote export done */
811                                 state = B_STATE_REMOTE;
812                         } else {
813                                 /* bchannel is now exported, but we need bchannel back
814                                  * OR bchannel is not used anymore
815                                  * OR bchannel has been exported to an obsolete ref,
816                                  * so reimport, to later export to new remote */
817                                 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
818                                 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
819                                 add_trace("type", NULL, "remove");
820                                 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
821                                 end_trace();
822                                 state = B_STATE_IMPORTING;
823                         }
824                         break;
825
826                         default:
827                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
828                 }
829                 break;
830
831                 case B_EVENT_DROP:
832                 if (!b_port)
833                         FATAL("bchannel must be linked to a Port class\n");
834                 switch(state) {
835                         case B_STATE_IDLE:
836                         /* bchannel is idle due to an error, so we do nothing */
837                         break;
838
839                         case B_STATE_ACTIVATING:
840                         case B_STATE_EXPORTING:
841                         /* do nothing because we must wait until bchanenl is active before deactivating */
842                         break;
843
844                         case B_STATE_ACTIVE:
845                         /* bchannel is active, so we deactivate */
846                         _bchannel_activate(mISDNport, i, 0, 0);
847                         state = B_STATE_DEACTIVATING;
848                         timer = B_TIMER_DEACTIVATING;
849                         break;
850
851                         case B_STATE_REMOTE:
852                         /* bchannel is exported, so we re-import */
853                         message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
854                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
855                         add_trace("type", NULL, "remove");
856                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
857                         end_trace();
858                         state = B_STATE_IMPORTING;
859                         break;
860
861                         case B_STATE_DEACTIVATING:
862                         case B_STATE_IMPORTING:
863                         /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
864                         break;
865
866                         default:
867                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
868                 }
869                 break;
870
871                 case B_EVENT_DEACTIVATED:
872                 timer = 0;
873                 switch(state) {
874                         case B_STATE_IDLE:
875                         /* ignore due to deactivation confirm after unloading */
876                         break;
877
878                         case B_STATE_DEACTIVATING:
879                         _bchannel_destroy(mISDNport, i);
880                         state = B_STATE_IDLE;
881                         if (b_port) {
882                                 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
883                                 if (p_m_remote_ref) {
884                                         message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
885                                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
886                                         add_trace("type", NULL, "assign");
887                                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
888                                         end_trace();
889                                         state = B_STATE_EXPORTING;
890                                         mISDNport->b_remote_id[i] = p_m_remote_id;
891                                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
892                                 } else {
893                                         if (_bchannel_create(mISDNport, i)) {
894                                                 _bchannel_activate(mISDNport, i, 1, 0);
895                                                 state = B_STATE_ACTIVATING;
896                                                 timer = B_TIMER_ACTIVATING;
897                                         }
898                                 }
899                         }
900                         break;
901
902                         default:
903                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
904                 }
905                 break;
906
907                 case B_EVENT_IMPORTED:
908                 switch(state) {
909                         case B_STATE_IMPORTING:
910                         state = B_STATE_IDLE;
911                         mISDNport->b_remote_id[i] = 0;
912                         mISDNport->b_remote_ref[i] = 0;
913                         if (b_port) {
914                                 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
915                                 if (p_m_remote_ref) {
916                                         message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
917                                         chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
918                                         add_trace("type", NULL, "assign");
919                                         add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
920                                         end_trace();
921                                         state = B_STATE_EXPORTING;
922                                         mISDNport->b_remote_id[i] = p_m_remote_id;
923                                         mISDNport->b_remote_ref[i] = p_m_remote_ref;
924                                 } else {
925                                         if (_bchannel_create(mISDNport, i)) {
926                                                 _bchannel_activate(mISDNport, i, 1, 0);
927                                                 state = B_STATE_ACTIVATING;
928                                                 timer = B_TIMER_ACTIVATING;
929                                         }
930                                 }
931                         }
932                         break;
933
934                         default:
935                         /* ignore, because not assigned */
936                         ;
937                 }
938                 break;
939
940                 case B_EVENT_TIMEOUT:
941                 timer = 0;
942                 switch(state) {
943                         case B_STATE_IDLE:
944                         /* ignore due to deactivation confirm after unloading */
945                         break;
946
947                         case B_STATE_ACTIVATING:
948                         _bchannel_activate(mISDNport, i, 1, 1);
949                         timer = B_TIMER_ACTIVATING;
950                         break;
951
952                         case B_STATE_DEACTIVATING:
953                         _bchannel_activate(mISDNport, i, 0, 1);
954                         timer = B_TIMER_DEACTIVATING;
955                         break;
956
957                         default:
958                         PERROR("Illegal event %d at state %d, please correct.\n", event, state);
959                 }
960                 break;
961
962                 default:
963                 PERROR("Illegal event %d, please correct.\n", event);
964         }
965
966         mISDNport->b_state[i] = state;
967         if (timer == 0)
968                 unsched_timer(&mISDNport->b_timer[i]);
969         else if (timer > 0)
970                 schedule_timer(&mISDNport->b_timer[i], timer, 0);
971 }
972
973
974
975
976 /*
977  * check for available channel and reserve+set it.
978  * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
979  * give exclusiv flag
980  * returns -(cause value) or x = channel x or 0 = no channel
981  * NOTE: no activation is done here
982  */
983 int PmISDN::seize_bchannel(int channel, int exclusive)
984 {
985         int i;
986
987         /* the channel is what we have */
988         if (p_m_b_channel == channel)
989                 return(channel);
990
991         /* if channel already in use, release it */
992         if (p_m_b_channel)
993                 drop_bchannel();
994
995         /* if CHANNEL_NO */
996         if (channel==CHANNEL_NO || channel==0)
997                 return(0);
998         
999         /* is channel in range ? */
1000         if (channel==16
1001          || (channel>p_m_mISDNport->b_num && channel<16)
1002          || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1003                 return(-6); /* channel unacceptable */
1004
1005         /* request exclusive channel */
1006         if (exclusive && channel>0) {
1007                 i = channel-1-(channel>16);
1008                 if (p_m_mISDNport->b_port[i])
1009                         return(-44); /* requested channel not available */
1010                 goto seize;
1011         }
1012
1013         /* ask for channel */
1014         if (channel>0) {
1015                 i = channel-1-(channel>16);
1016                 if (p_m_mISDNport->b_port[i] == NULL)
1017                         goto seize;
1018         }
1019
1020         /* search for channel */
1021         i = 0;
1022         while(i < p_m_mISDNport->b_num) {
1023                 if (!p_m_mISDNport->b_port[i]) {
1024                         channel = i+1+(i>=15);
1025                         goto seize;
1026                 }
1027                 i++;
1028         }
1029         return(-34); /* no free channel */
1030
1031 seize:
1032         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1033
1034         /* link Port, set parameters */
1035         p_m_mISDNport->b_port[i] = this;
1036         p_m_b_index = i;
1037         p_m_b_channel = channel;
1038         p_m_b_exclusive = exclusive;
1039         p_m_mISDNport->b_mode[i] = p_m_b_mode;
1040
1041         /* reserve channel */
1042         if (!p_m_b_reserve) {
1043                 p_m_b_reserve = 1;
1044                 p_m_mISDNport->b_reserved++;
1045         }
1046
1047         return(channel);
1048 }
1049
1050 /*
1051  * drop reserved channel and unset it.
1052  * deactivation is also done
1053  */
1054 void PmISDN::drop_bchannel(void)
1055 {
1056         /* unreserve channel */
1057         if (p_m_b_reserve)
1058                 p_m_mISDNport->b_reserved--;
1059         p_m_b_reserve = 0;
1060
1061         /* if not in use */
1062         if (p_m_b_index < 0)
1063                 return;
1064         if (!p_m_b_channel)
1065                 return;
1066
1067         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1068
1069         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1070                 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1071         p_m_mISDNport->b_port[p_m_b_index] = NULL;
1072         p_m_mISDNport->b_mode[p_m_b_index] = 0;
1073         p_m_b_index = -1;
1074         p_m_b_channel = 0;
1075         p_m_b_exclusive = 0;
1076 }
1077
1078 /* process bchannel export/import message from join */
1079 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1080 {
1081         class Endpoint *epoint;
1082         class Port *port;
1083         class PmISDN *isdnport;
1084         struct mISDNport *mISDNport;
1085         int i, ii;
1086
1087         switch(type) {
1088                 case BCHANNEL_REQUEST:
1089                 /* find the port object for the join object ref */
1090                 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1091                         PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1092                         return;
1093                 }
1094                 if (!epoint->ep_portlist) {
1095                         PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1096                         return;
1097                 }
1098                 if (epoint->ep_portlist->next) {
1099                         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);
1100                 }
1101                 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1102                         PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1103                         return;
1104                 }
1105                 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1106                         PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1107                 }
1108                 isdnport = (class PmISDN *)port;
1109
1110                 /* assign */
1111                 if (isdnport->p_m_remote_id) {
1112                         PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1113                         break;
1114                 }
1115                 mISDNport = isdnport->p_m_mISDNport;
1116                 i = isdnport->p_m_b_index;
1117                 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1118                 add_trace("type", NULL, "export request");
1119                 end_trace();
1120                 isdnport->p_m_remote_ref = joinremote->j_serial;
1121                 isdnport->p_m_remote_id = joinremote->j_remote_id;
1122                 if (mISDNport && i>=0) {
1123                         bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1124                 }
1125                 break;
1126
1127                 case BCHANNEL_RELEASE:
1128                 case BCHANNEL_ASSIGN_ACK:
1129                 case BCHANNEL_REMOVE_ACK:
1130                 /* find mISDNport for stack ID */
1131                 mISDNport = mISDNport_first;
1132                 while(mISDNport) {
1133                         i = 0;
1134                         ii = mISDNport->b_num;
1135                         while(i < ii) {
1136                                 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1137                                         break;
1138                                 i++;
1139                         }
1140                         if (i != ii)
1141                                 break;
1142                         mISDNport = mISDNport->next;
1143                 }
1144                 if (!mISDNport) {
1145                         PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1146                         break;
1147                 }
1148                 
1149                 if (type!=BCHANNEL_RELEASE) {
1150                         /* ack */
1151                         chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1152                         add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1153                         end_trace();
1154                         bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1155                 } else {
1156                         /* release */
1157                         isdnport = mISDNport->b_port[i];
1158                         chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1159                         add_trace("type", NULL, "import request");
1160                         end_trace();
1161                         if (isdnport) {
1162                                 isdnport->p_m_remote_ref = 0;
1163                                 isdnport->p_m_remote_id = 0;
1164                         }
1165                         bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1166                 }
1167                 break;
1168                 default:
1169                 PERROR("received wrong bchannel message type %d from remote\n", type);
1170         }
1171 }
1172
1173
1174 /*
1175  * handler
1176
1177 audio transmission procedure:
1178 -----------------------------
1179
1180 * priority
1181 three sources of audio transmission:
1182 - crypto-data high priority
1183 - tones high priority (also high)
1184 - remote-data low priority
1185
1186 * elapsed
1187 a variable that temporarily shows the number of samples elapsed since last transmission process.
1188 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1189
1190 * load
1191 a variable that is increased whenever data is transmitted.
1192 it is decreased while time elapses. it stores the number of samples that
1193 are currently loaded to dsp module.
1194 since clock in dsp module is the same clock for user space process, these 
1195 times have no skew.
1196
1197 * levels
1198 there are two levels:
1199 ISDN_LOAD will give the load that have to be kept in dsp.
1200 ISDN_MAXLOAD will give the maximum load before dropping.
1201
1202 * procedure for low priority data
1203 see txfromup() for procedure
1204 in short: remote data is ignored during high priority tones
1205
1206 * procedure for high priority data
1207 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1208 if no more data is available, load becomes empty again.
1209
1210 'load' variable:
1211 0                    ISDN_LOAD           ISDN_MAXLOAD
1212 +--------------------+----------------------+
1213 |                    |                      |
1214 +--------------------+----------------------+
1215
1216 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1217 0                    ISDN_LOAD           ISDN_MAXLOAD
1218 +--------------------+----------------------+
1219 |TTTTTTTTTTTTTTTTTTTT|                      |
1220 +--------------------+----------------------+
1221
1222 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1223 0                    ISDN_LOAD           ISDN_MAXLOAD
1224 +--------------------+----------------------+
1225 |TTTTTTTTTTTTTTTTTTTTRRRRR                  |
1226 +--------------------+----------------------+
1227
1228  */
1229 void PmISDN::update_load(void)
1230 {
1231         /* don't trigger load event if: */
1232         if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1233                 return;
1234
1235         /* don't trigger load event if event already active */
1236         if (p_m_loadtimer.active)
1237                 return;
1238
1239         schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1240 }
1241
1242 int load_timer(struct lcr_timer *timer, void *instance, int index)
1243 {
1244         class PmISDN *isdnport = (class PmISDN *)instance;
1245
1246         isdnport->load_tx();
1247
1248         return 0;
1249 }
1250
1251 void PmISDN::load_tx(void)
1252 {
1253         int elapsed = 0;
1254         int ret;
1255         struct timeval current_time;
1256
1257         /* get elapsed */
1258         gettimeofday(&current_time, NULL);
1259         if (p_m_last_tv_sec) {
1260                 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1261                         + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1262         }
1263         /* set clock of last process! */
1264         p_m_last_tv_sec = current_time.tv_sec;
1265         p_m_last_tv_msec = current_time.tv_usec/1000;
1266
1267         /* process only if we have samples and we are active */
1268         if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1269                 /* update load */
1270                 if (elapsed < p_m_load)
1271                         p_m_load -= elapsed;
1272                 else
1273                         p_m_load = 0;
1274
1275                 /* to send data, tone must be on */
1276                 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1277                  && (p_m_load < ISDN_LOAD) /* not too much load? */
1278                  && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1279                         int tosend = ISDN_LOAD - p_m_load, length; 
1280                         unsigned char buf[MISDN_HEADER_LEN+tosend];
1281                         struct mISDNhead *frm = (struct mISDNhead *)buf;
1282                         unsigned char *p = buf+MISDN_HEADER_LEN;
1283
1284                         /* copy inband signalling (e.g. used by ss5) */
1285                         if (p_m_inband_send_on && tosend) {
1286                                 tosend -= inband_send(p, tosend);
1287                         }
1288
1289                         /* copy crypto loops */
1290                         while (p_m_crypt_msg_loops && tosend) {
1291                                 /* how much do we have to send */
1292                                 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1293
1294                                 /* clip tosend */
1295                                 if (length > tosend)
1296                                         length = tosend;
1297
1298                                 /* copy message (part) to buffer */
1299                                 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1300
1301                                 /* new position */
1302                                 p_m_crypt_msg_current += length;
1303                                 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1304                                         /* next loop */
1305                                         p_m_crypt_msg_current = 0;
1306                                         p_m_crypt_msg_loops--;
1307                                         if (!p_m_crypt_msg_loops)
1308                                                 update_rxoff();
1309 //                                      puts("eine loop weniger");
1310                                 }
1311
1312                                 /* new length */
1313                                 tosend -= length;
1314                         }
1315
1316                         /* copy tones */
1317                         if (p_tone_name[0] && tosend) {
1318                                 tosend -= read_audio(p, tosend);
1319                         }
1320
1321                         /* send data */
1322                         if (ISDN_LOAD - p_m_load - tosend > 0) {
1323                                 frm->prim = PH_DATA_REQ;
1324                                 frm->id = 0;
1325                                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1326                                 if (ret <= 0)
1327                                         PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_sock[p_m_b_index].fd, ISDN_LOAD-p_m_load-tosend);
1328                                 p_m_load += ISDN_LOAD - p_m_load - tosend;
1329                         }
1330                 }
1331         }
1332
1333         if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1334                 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
1335         }
1336 }
1337
1338 /* handle timeouts */
1339 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1340 {
1341         class PmISDN *isdnport = (class PmISDN *)instance;
1342         struct lcr_msg *message;
1343
1344         PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", isdnport->p_name, isdnport->p_m_timeout.timeout.tv_sec, isdnport->p_state);
1345         /* send timeout to endpoint */
1346         message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1347         message->param.state = isdnport->p_state;
1348         message_put(message);
1349
1350         return 0;
1351 }
1352         
1353
1354 /*
1355  * whenever we get audio data from bchannel, we process it here
1356  */
1357 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1358 {
1359         unsigned int cont = *((unsigned int *)data);
1360         unsigned char *data_temp;
1361         unsigned int length_temp;
1362         struct lcr_msg *message;
1363         unsigned char *p;
1364         int l;
1365
1366         if (hh->prim == PH_CONTROL_IND) {
1367                 if (len < 4) {
1368                         PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1369                         return;
1370                 }
1371                 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1372                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1373                         add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1374                         end_trace();
1375                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1376                         message->param.dtmf = cont & DTMF_TONE_MASK;
1377                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  DTMF digit '%c'\n", p_name, message->param.dtmf);
1378                         message_put(message);
1379                         return;
1380                 }
1381                 switch(cont) {
1382                         case DSP_BF_REJECT:
1383                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1384                         add_trace("DSP-CRYPT", NULL, "error");
1385                         end_trace();
1386                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1387                         message->param.crypt.type = CC_ERROR_IND;
1388                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  reject of blowfish.\n", p_name);
1389                         message_put(message);
1390                         break;
1391
1392                         case DSP_BF_ACCEPT:
1393                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1394                         add_trace("DSP-CRYPT", NULL, "ok");
1395                         end_trace();
1396                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1397                         message->param.crypt.type = CC_ACTBF_CONF;
1398                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  accept of blowfish.\n", p_name);
1399                         message_put(message);
1400                         break;
1401
1402                         default:
1403                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1404                         add_trace("unknown", NULL, "0x%x", cont);
1405                         end_trace();
1406                 }
1407                 return;
1408         }
1409         if (hh->prim == PH_CONTROL_IND) {
1410                 switch(hh->id) {
1411                         default:
1412                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1413                         add_trace("unknown", NULL, "0x%x", hh->id);
1414                         end_trace();
1415                 }
1416                 return;
1417         }
1418         if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1419                 if (!p_m_txdata) {
1420                         /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1421                         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1422                         return;
1423                 }
1424                 /* see below (same condition) */
1425                 if (p_state!=PORT_STATE_CONNECT
1426                          && !p_m_mISDNport->tones)
1427                         return;
1428 //              printf(".");fflush(stdout);return;
1429                 if (p_record)
1430                         record(data, len, 1); // from up
1431                 return;
1432         }
1433         if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1434                 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1435                 return;
1436         }
1437
1438         /* inband is processed */
1439         if (p_m_inband_receive_on)
1440                 inband_receive(data, len);
1441
1442         /* calls will not process any audio data unless
1443          * the call is connected OR tones feature is enabled.
1444          */
1445 #ifndef DEBUG_COREBRIDGE
1446         if (p_state!=PORT_STATE_CONNECT
1447          && !p_m_mISDNport->tones)
1448                 return;
1449 #endif
1450
1451 #if 0
1452         /* the bearer capability must be audio in order to send and receive
1453          * audio prior or after connect.
1454          */
1455         if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1456                 return;
1457 #endif
1458
1459         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1460         if (p_m_rxoff) {
1461                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1462                 return;
1463         }
1464
1465         /* record data */
1466         if (p_record)
1467                 record(data, len, 0); // from down
1468
1469         /* randomize and listen to crypt message if enabled */
1470         if (p_m_crypt_listen) {
1471                 /* the noisy randomizer */
1472                 p = data;
1473                 l = len;
1474                 while(l--)
1475                         mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1476
1477                 cryptman_listen_bch(data, len);
1478         }
1479
1480         p = data;
1481
1482         /* send data to epoint */
1483         if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1484                 length_temp = len;
1485                 data_temp = p;
1486                 while(length_temp) {
1487                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1488                         message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1489                         memcpy(message->param.data.data, data_temp, message->param.data.len);
1490                         message_put(message);
1491                         if (length_temp <= sizeof(message->param.data.data))
1492                                 break;
1493                         data_temp += sizeof(message->param.data.data);
1494                         length_temp -= sizeof(message->param.data.data);
1495                 }
1496         }
1497 }
1498
1499
1500 /*
1501  * set echotest
1502  */
1503 void PmISDN::set_echotest(int echo)
1504 {
1505         if (p_m_echo != echo) {
1506                 p_m_echo = echo;
1507                 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1508                 if (p_m_b_channel)
1509                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1510                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1511         }
1512 }
1513
1514 /*
1515  * set tone
1516  */
1517 void PmISDN::set_tone(const char *dir, const char *tone)
1518 {
1519         int id = TONE_OFF;
1520         int dsp = DSP_NONE;
1521
1522         /* if no directory is given (by extension), we use interface.conf or options.conf */
1523         if (!dir || !dir[0]) {
1524                 if (p_m_mISDNport->ifport->tones_dir[0])
1525                         dir = p_m_mISDNport->ifport->tones_dir;
1526                 else if (options.tones_dir[0])
1527                         dir = options.tones_dir;
1528         }
1529
1530         if (!tone)
1531                 tone = "";
1532         PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1533         if (!tone[0]) {
1534                 id = TONE_OFF;
1535                 goto setdsp;
1536         }
1537
1538         /* check for dsp tones */
1539         if (!strcmp(dir, "american"))
1540                 dsp = DSP_AMERICAN;
1541         if (!strcmp(dir, "german"))
1542                 dsp = DSP_GERMAN;
1543         if (!strcmp(dir, "oldgerman"))
1544                 dsp = DSP_OLDGERMAN;
1545
1546         /* check if we NOT really have to use a dsp-tone */
1547         if (dsp == DSP_NONE) {
1548                 nodsp:
1549                 if (p_m_tone)
1550                 if (p_m_b_index > -1)
1551                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1552                         PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1553                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1554                 }
1555                 p_m_tone = 0;
1556                 Port::set_tone(dir, tone);
1557                 return;
1558         }
1559
1560         /* now we USE dsp-tone, convert name */
1561         if (!strcmp(tone, "dialtone")) {
1562                 switch(dsp) {
1563                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1564                 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1565                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1566                 }
1567         } else if (!strcmp(tone, "dialpbx")) {
1568                 switch(dsp) {
1569                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1570                 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1571                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1572                 }
1573         } else if (!strcmp(tone, "ringing")) {
1574                 switch(dsp) {
1575                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1576                 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1577                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1578                 }
1579         } else if (!strcmp(tone, "ringpbx")) {
1580                 switch(dsp) {
1581                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1582                 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1583                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1584                 }
1585         } else if (!strcmp(tone, "busy")) {
1586                 busy:
1587                 switch(dsp) {
1588                 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1589                 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1590                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1591                 }
1592         } else if (!strcmp(tone, "release")) {
1593                 hangup:
1594                 switch(dsp) {
1595                 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1596                 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1597                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1598                 }
1599         } else if (!strcmp(tone, "cause_10"))
1600                 goto hangup;
1601         else if (!strcmp(tone, "cause_11"))
1602                 goto busy;
1603         else if (!strcmp(tone, "cause_22")) {
1604                 switch(dsp) {
1605                 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1606                 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1607                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1608                 }
1609         } else if (!strncmp(tone, "cause_", 6))
1610                 id = TONE_SPECIAL_INFO;
1611         else
1612                 id = TONE_OFF;
1613
1614         /* if we have a tone that is not supported by dsp */
1615         if (id==TONE_OFF && tone[0])
1616                 goto nodsp;
1617
1618         setdsp:
1619         if (p_m_tone != id) {
1620                 /* set new tone */
1621                 p_m_tone = id;
1622                 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1623                 if (p_m_b_index > -1)
1624                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1625                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1626         }
1627         /* turn user-space tones off in cases of no tone OR dsp tone */
1628         Port::set_tone("",NULL);
1629 }
1630
1631
1632 /* MESSAGE_mISDNSIGNAL */
1633 //extern struct lcr_msg *dddebug;
1634 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1635 {
1636         int oldconf, newconf;
1637         switch(param->mISDNsignal.message) {
1638                 case mISDNSIGNAL_VOLUME:
1639                 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1640                         p_m_tx_gain = param->mISDNsignal.tx_gain;
1641                         PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1642                         if (p_m_b_index > -1)
1643                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1644                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1645                 } else
1646                         PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1647                 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1648                         p_m_rx_gain = param->mISDNsignal.rx_gain;
1649                         PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1650                         if (p_m_b_index > -1)
1651                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1652                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1653                 } else
1654                         PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1655                 break;
1656
1657                 case mISDNSIGNAL_CONF:
1658                 oldconf = p_m_mute?0:p_m_conf;
1659                 p_m_conf = param->mISDNsignal.conf;
1660                 newconf = p_m_mute?0:p_m_conf;
1661                 set_conf(oldconf, newconf);
1662                 break;
1663
1664                 case mISDNSIGNAL_JOINDATA:
1665                 if (p_m_joindata != param->mISDNsignal.joindata) {
1666                         p_m_joindata = param->mISDNsignal.joindata;
1667                         PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1668                         update_rxoff();
1669                 } else
1670                         PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1671                 break;
1672                 
1673                 case mISDNSIGNAL_DELAY:
1674                 if (p_m_delay != param->mISDNsignal.delay) {
1675                         p_m_delay = param->mISDNsignal.delay;
1676                         PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1677                         if (p_m_b_index > -1)
1678                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1679                                 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1680                 } else
1681                         PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1682                 break;
1683
1684                 default:
1685                 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1686         }
1687 }
1688
1689 /* MESSAGE_CRYPT */
1690 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1691 {
1692         struct lcr_msg *message;
1693
1694         switch(param->crypt.type) {
1695                 case CC_ACTBF_REQ:           /* activate blowfish */
1696                 p_m_crypt = 1;
1697                 p_m_crypt_key_len = param->crypt.len;
1698                 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1699                         PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1700                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1701                         message->param.crypt.type = CC_ERROR_IND;
1702                         message_put(message);
1703                         break;
1704                 }
1705                 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1706                 crypt_off:
1707                 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1708                 if (p_m_b_index > -1)
1709                 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1710                         ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1711                 break;
1712
1713                 case CC_DACT_REQ:            /* deactivate session encryption */
1714                 p_m_crypt = 0;
1715                 goto crypt_off;
1716                 break;
1717
1718                 case CR_LISTEN_REQ:          /* start listening to messages */
1719                 p_m_crypt_listen = 1;
1720                 update_rxoff();
1721                 p_m_crypt_listen_state = 0;
1722                 break;
1723
1724                 case CR_UNLISTEN_REQ:        /* stop listening to messages */
1725                 p_m_crypt_listen = 0;
1726                 update_rxoff();
1727                 break;
1728
1729                 case CR_MESSAGE_REQ:         /* send message */
1730                 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1731                 if (!p_m_crypt_msg_len) {
1732                         PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1733                         break;
1734                 }
1735                 p_m_crypt_msg_current = 0; /* reset */
1736                 p_m_crypt_msg_loops = 6; /* enable */
1737                 update_rxoff();
1738                 update_load();
1739 #if 0
1740                 /* disable txmix, or we get corrupt data due to audio process */
1741                 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1742                         PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1743                         ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1744                 }
1745 #endif
1746                 break;
1747
1748                 default:
1749                 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1750         }
1751
1752 }
1753
1754 /*
1755  * endpoint sends messages to the port
1756  */
1757 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1758 {
1759         if (Port::message_epoint(epoint_id, message_id, param))
1760                 return(1);
1761
1762         switch(message_id) {
1763                 case MESSAGE_DATA: /* tx-data from upper layer */
1764                 txfromup(param->data.data, param->data.len);
1765                 return(1);
1766
1767                 case MESSAGE_mISDNSIGNAL: /* user command */
1768                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1769                 message_mISDNsignal(epoint_id, message_id, param);
1770                 return(1);
1771
1772                 case MESSAGE_CRYPT: /* crypt control command */
1773                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1774                 message_crypt(epoint_id, message_id, param);
1775                 return(1);
1776         }
1777
1778         return(0);
1779 }
1780
1781 void PmISDN::update_rxoff(void)
1782 {
1783         /* call bridges in user space OR crypto OR recording */
1784         if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1785                 /* rx IS required */
1786                 if (p_m_rxoff) {
1787                         /* turn on RX */
1788                         p_m_rxoff = 0;
1789                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1790                         if (p_m_b_index > -1)
1791                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1792                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1793                 }
1794         } else {
1795                 /* rx NOT required */
1796                 if (!p_m_rxoff) {
1797                         /* turn off RX */
1798                         p_m_rxoff = 1;
1799                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1800                         if (p_m_b_index > -1)
1801                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1802                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1803                 }
1804         }
1805         /* recording */
1806         if (p_record) {
1807                 /* txdata IS required */
1808                 if (!p_m_txdata) {
1809                         /* turn on RX */
1810                         p_m_txdata = 1;
1811                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1812                         if (p_m_b_index > -1)
1813                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1814                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1815                 }
1816         } else {
1817                 /* txdata NOT required */
1818                 if (p_m_txdata) {
1819                         /* turn off RX */
1820                         p_m_txdata = 0;
1821                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1822                         if (p_m_b_index > -1)
1823                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1824                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1825                 }
1826         }
1827 }
1828
1829 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1830 {
1831         struct mISDNport *mISDNport;
1832         struct mbuffer *mb;
1833         struct l3_msg *l3m;
1834         char byte;
1835
1836         /* unset global semaphore */
1837         upqueue_avail = 0;
1838         // with a very small incident, upqueue_avail may be set by mISDN thread and
1839         // another byte may be sent to the pipe, which causes a call to this function
1840         // again with nothing in the upqueue. this is no problem.
1841         read(fd->fd, &byte, 1);
1842
1843         /* process all ports */
1844         mISDNport = mISDNport_first;
1845         while(mISDNport) {
1846                 /* handle queued up-messages (d-channel) */
1847                 if (!mISDNport->gsm) {
1848                         while ((mb = mdequeue(&mISDNport->upqueue))) {
1849                                 l3m = &mb->l3;
1850                                 switch(l3m->type) {
1851                                         case MPH_ACTIVATE_IND:
1852                                         if (mISDNport->l1link != 1) {
1853                                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1854                                                 end_trace();
1855                                                 mISDNport->l1link = 1;
1856                                         }
1857                                         break;
1858                 
1859                                         case MPH_DEACTIVATE_IND:
1860                                         if (mISDNport->l1link != 0) {
1861                                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1862                                                 end_trace();
1863                                                 mISDNport->l1link = 0;
1864                                         }
1865                                         break;
1866
1867                                         case MPH_INFORMATION_IND:
1868                                         PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1869                                         switch (l3m->pid) {
1870                                                 case L1_SIGNAL_LOS_ON:
1871                                                 mISDNport->los = 1;
1872                                                 break;
1873                                                 case L1_SIGNAL_LOS_OFF:
1874                                                 mISDNport->los = 0;
1875                                                 break;
1876                                                 case L1_SIGNAL_AIS_ON:
1877                                                 mISDNport->ais = 1;
1878                                                 break;
1879                                                 case L1_SIGNAL_AIS_OFF:
1880                                                 mISDNport->ais = 0;
1881                                                 break;
1882                                                 case L1_SIGNAL_RDI_ON:
1883                                                 mISDNport->rdi = 1;
1884                                                 break;
1885                                                 case L1_SIGNAL_RDI_OFF:
1886                                                 mISDNport->rdi = 0;
1887                                                 break;
1888                                                 case L1_SIGNAL_SLIP_TX:
1889                                                 mISDNport->slip_tx++;
1890                                                 break;
1891                                                 case L1_SIGNAL_SLIP_RX:
1892                                                 mISDNport->slip_rx++;
1893                                                 break;
1894                                         }
1895                                         break;
1896
1897                                         case MT_L2ESTABLISH:
1898                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1899                                         add_trace("tei", NULL, "%d", l3m->pid);
1900                                         end_trace();
1901                                         mISDNport->l2link = 1;
1902                                         if (l3m->pid < 128)
1903                                                 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1904                                         if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1905                                                 if (mISDNport->l2establish.active) {
1906                                                         unsched_timer(&mISDNport->l2establish);
1907                                                         PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1908                                                 }
1909                                         }
1910                                         break;
1911
1912                                         case MT_L2RELEASE:
1913                                         if (l3m->pid < 128)
1914                                                 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1915                                         if (!mISDNport->l2establish.active) {
1916                                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1917                                                 add_trace("tei", NULL, "%d", l3m->pid);
1918                                                 end_trace();
1919                                                 /* down if not nt-ptmp */ 
1920                                                 if (!mISDNport->ntmode || mISDNport->ptp)
1921                                                         mISDNport->l2link = 0;
1922                                         }
1923                                         if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1924                                                 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1925                                                         PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1926                                                         schedule_timer(&mISDNport->l2establish, 5, 0);
1927                                                         mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1928                                                 }
1929                                         }
1930                                         break;
1931
1932                                         default:
1933                                         /* l3-data is sent to LCR */
1934                                         stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1935                                 }
1936                                 /* free message */
1937                                 free_l3_msg(l3m);
1938                         }
1939                 }
1940                 mISDNport = mISDNport->next;
1941         }
1942         return 0;
1943 }
1944
1945 /* l2 establish timer fires */
1946 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1947 {
1948         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1949
1950         if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1951 //              PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1952                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1953                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1954         }
1955
1956         return 0;
1957 }
1958
1959 /* handle frames from bchannel */
1960 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1961 {
1962         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1963         unsigned char buffer[2048+MISDN_HEADER_LEN];
1964         struct mISDNhead *hh = (struct mISDNhead *)buffer;
1965         int ret;
1966
1967         ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1968         if (ret < 0) {
1969                 PERROR("read error frame, errno %d\n", errno);
1970                 return 0;
1971         }
1972         if (ret < (int)MISDN_HEADER_LEN) {
1973                 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1974                 return 0;
1975         }
1976         switch(hh->prim) {
1977                 /* we don't care about confirms, we use rx data to sync tx */
1978                 case PH_DATA_CNF:
1979                 break;
1980
1981                 /* we receive audio data, we respond to it AND we send tones */
1982                 case PH_DATA_IND:
1983                 case DL_DATA_IND:
1984                 case PH_DATA_REQ:
1985                 case DL_DATA_REQ:
1986                 case PH_CONTROL_IND:
1987                 if (mISDNport->b_port[i])
1988                         mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1989                 else
1990                         PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1991                 break;
1992
1993                 case PH_ACTIVATE_IND:
1994                 case DL_ESTABLISH_IND:
1995                 case PH_ACTIVATE_CNF:
1996                 case DL_ESTABLISH_CNF:
1997                 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1998                 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1999                 break;
2000
2001                 case PH_DEACTIVATE_IND:
2002                 case DL_RELEASE_IND:
2003                 case PH_DEACTIVATE_CNF:
2004                 case DL_RELEASE_CNF:
2005                 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2006                 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2007                 break;
2008
2009                 default:
2010                 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2011         }
2012
2013         return 0;
2014 }
2015
2016 /* process timer events for bchannel handling */
2017 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2018 {
2019         struct mISDNport *mISDNport = (struct mISDNport *)instance;
2020 puts("fires");
2021
2022         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2023
2024         return 0;
2025 }
2026
2027
2028 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2029 {
2030         /* IMPORTAINT:
2031          *
2032          * l3m must be queued, except for MT_ASSIGN
2033          *
2034          */
2035         struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2036         struct mbuffer *mb;
2037
2038         /* special MT_ASSIGN handling:
2039          *
2040          * if we request a PID from mlayer, we always do it while lcr is locked.
2041          * therefore we must check the MT_ASSIGN reply first before we lock.
2042          * this is because the MT_ASSIGN reply is received with the requesting
2043          * process, not by the mlayer thread!
2044          * this means, that the reply is sent during call of the request.
2045          * we must check if we get a reply and we know that we lcr is currently
2046          * locked.
2047          */
2048         if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2049                 /* let's do some checking if someone changes stack behaviour */
2050                 if (mt_assign_pid != 0)
2051                         FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2052                 mt_assign_pid = pid;
2053                 return(0);
2054         }
2055         /* queue message, create, if required */
2056         if (!l3m) {
2057                 l3m = alloc_l3_msg();
2058                 if (!l3m)
2059                         FATAL("No memory for layer 3 message\n");
2060         }
2061         mb = container_of(l3m, struct mbuffer, l3);
2062         l3m->type = cmd;
2063         l3m->pid = pid;
2064         mqueue_tail(&mISDNport->upqueue, mb);
2065         if (!upqueue_avail) {
2066                 // multiple threads may cause multiple calls of this section, but this
2067                 // results only in multiple processing of the upqueue read.
2068                 // this is no problem.
2069                 upqueue_avail = 1;
2070                 char byte = 0;
2071                 write(upqueue_pipe[1], &byte, 1);
2072         }
2073         return 0;
2074 }
2075
2076 int mISDN_getportbyname(int sock, int cnt, char *portname)
2077 {
2078         struct mISDN_devinfo devinfo;
2079         int port = 0, ret;
2080
2081         /* resolve name */
2082         while (port < cnt) {
2083                 devinfo.id = port;
2084                 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2085                 if (ret < 0)
2086                         return ret;
2087                 if (!strcasecmp(devinfo.name, portname))
2088                         break;
2089                 port++;
2090         }
2091         if (port == cnt)
2092                 return -EIO;
2093
2094         return (port);
2095 }
2096
2097 /*
2098  * global function to add a new card (port)
2099  */
2100 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2101 {
2102         int ret;
2103         struct mISDNport *mISDNport, **mISDNportp;
2104         int port = ifport->portnum;
2105         int ptp = ifport->ptp;
2106         int force_nt = ifport->nt;
2107         int l1hold = ifport->l1hold;
2108         int l2hold = ifport->l2hold;
2109         int gsm = ifport->gsm;
2110         int ss5 = ifport->ss5;
2111         int i, cnt;
2112         int pri, bri, pots;
2113         int nt, te;
2114 //      struct mlayer3 *ml3;
2115         struct mISDN_devinfo devinfo;
2116         unsigned int protocol, prop;
2117
2118         /* check port counts */
2119         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2120         if (ret < 0) {
2121                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2122                 return(NULL);
2123         }
2124
2125         if (cnt <= 0) {
2126                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2127                 return(NULL);
2128         }
2129         if (port < 0) {
2130                 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2131                 if (port < 0) {
2132                         if (gsm)
2133                                 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
2134                         else
2135                                 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2136                         return(NULL);
2137                 }
2138                 // note: 'port' has still the port number
2139         }
2140         if (port>cnt || port<0) {
2141                 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2142                 return(NULL);
2143         }
2144
2145         /* get port attributes */
2146         pri = bri = pots = nt = te = 0;
2147         devinfo.id = port;
2148         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2149         if (ret < 0) {
2150                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2151                 return(NULL);
2152         }
2153         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2154                 bri = 1;
2155                 te = 1;
2156         }
2157         if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2158                 bri = 1;
2159                 nt = 1;
2160         }
2161         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2162                 pri = 1;
2163                 te = 1;
2164         }
2165         if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2166                 pri = 1;
2167                 nt = 1;
2168         }
2169 #ifdef ISDN_P_FXS
2170         if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2171                 pots = 1;
2172                 te = 1;
2173         }
2174 #endif
2175 #ifdef ISDN_P_FXO
2176         if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2177                 pots = 1;
2178                 nt = 1;
2179         }
2180 #endif
2181         if (force_nt && !nt) {
2182                 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2183                 return(NULL);
2184         }
2185         if (bri && pri) {
2186                 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2187                 return(NULL);
2188         }
2189         if (pots && !bri && !pri) {
2190                 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2191                 return(NULL);
2192         }
2193         if (!bri && !pri) {
2194                 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2195                 return(NULL);
2196         }
2197         if (!nt && !te) {
2198                 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2199                 return(NULL);
2200         }
2201         /* set NT by turning off TE */
2202         if (force_nt && nt)
2203                 te = 0;
2204         /* if TE an NT is supported (and not forced to NT), turn off NT */
2205         if (te && nt)
2206                 nt = 0;
2207
2208         /* check for double use of port */
2209         if (nt) {
2210                 mISDNport = mISDNport_first;
2211                 while(mISDNport) {
2212                         if (mISDNport->portnum == port)
2213                                 break;
2214                         mISDNport = mISDNport->next;
2215                 }
2216                 if (mISDNport) {
2217                         PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2218                         return(NULL);
2219                 }
2220         }
2221
2222         /* check for continous channelmap with no bchannel on slot 16 */
2223         if (test_channelmap(0, devinfo.channelmap)) {
2224                 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2225                 return(NULL);
2226         }
2227         i = 1;
2228         while(i < (int)devinfo.nrbchan + 1) {
2229                 if (i == 16) {
2230                         if (test_channelmap(i, devinfo.channelmap)) {
2231                                 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2232                                 return(NULL);
2233                         }
2234                 } else {
2235                         if (!test_channelmap(i, devinfo.channelmap)) {
2236                                 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2237                                 return(NULL);
2238                         }
2239                 }
2240                 i++;
2241         }
2242
2243         /* add mISDNport structure */
2244         mISDNportp = &mISDNport_first;
2245         while(*mISDNportp)
2246                 mISDNportp = &((*mISDNportp)->next);
2247         mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2248         add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2249         if (gsm | ss5) {
2250                 /* gsm/ss5 link is always active */
2251                 mISDNport->l1link = 1;
2252                 mISDNport->l2link = 1;
2253         } else {
2254                 mISDNport->l1link = -1;
2255                 mISDNport->l2link = -1;
2256         }
2257         mISDNport->gsm = gsm;
2258         pmemuse++;
2259         *mISDNportp = mISDNport;
2260
2261         /* if pri, must set PTP */
2262         if (pri)
2263                 ptp = 1;
2264
2265         /* set ss5 params */
2266         if (ss5) {
2267                 /* try to keep interface enabled */
2268                 l1hold = 1;
2269                 l2hold = 1;
2270         }
2271         /* set l2hold */
2272         switch (l2hold) {
2273                 case -1: // off
2274                 l2hold = 0;
2275                 break;
2276                 case 1: // on
2277                 l2hold = 1;
2278                 break;
2279                 default:
2280                 if (ptp)
2281                         l2hold = 1;
2282                 else
2283                         l2hold = 0;
2284                 break;
2285         }
2286                 
2287         /* allocate ressources of port */
2288         protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2289         prop = (1 << MISDN_FLG_L2_CLEAN);
2290         if (ptp) // ptp forced
2291                prop |= (1 << MISDN_FLG_PTP);
2292         if (nt) // supports hold/retrieve on nt-mode
2293                prop |= (1 << MISDN_FLG_NET_HOLD);
2294         if (l1hold) // supports layer 1 hold
2295                prop |= (1 << MISDN_FLG_L1_HOLD);
2296         if (l2hold) // supports layer 2 hold
2297                prop |= (1 << MISDN_FLG_L2_HOLD);
2298         /* open layer 3 and init upqueue */
2299         if (gsm) {
2300                 unsigned long on = 1;
2301                 struct sockaddr_mISDN addr;
2302
2303                 if (devinfo.nrbchan < 8) {
2304                         PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2305                         mISDNport_close(mISDNport);
2306                         return(NULL);
2307                 }
2308
2309                 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2310                         PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2311                         mISDNport_close(mISDNport);
2312                         return(NULL);
2313                 }
2314                 /* set nonblocking io */
2315                 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2316                         PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2317                         mISDNport_close(mISDNport);
2318                         return(NULL);
2319                 }
2320                 /* bind socket to dchannel */
2321                 memset(&addr, 0, sizeof(addr));
2322                 addr.family = AF_ISDN;
2323                 addr.dev = port;
2324                 addr.channel = 0;
2325                 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2326                         PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2327                         mISDNport_close(mISDNport);
2328                         return(NULL);
2329                 }
2330         } else {
2331                 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2332                 mqueue_init(&mISDNport->upqueue);
2333                 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2334                 if (!mISDNport->ml3) {
2335                         mqueue_purge(&mISDNport->upqueue);
2336                         PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2337                         start_trace(port,
2338                                 ifport->interface,
2339                                 NULL,
2340                                 NULL,
2341                                 DIRECTION_NONE,
2342                                 CATEGORY_CH,
2343                                 0,
2344                                 "PORT (open failed)");
2345                         end_trace();
2346                         mISDNport_close(mISDNport);
2347                         return(NULL);
2348                 }
2349         }
2350
2351         SCPY(mISDNport->name, devinfo.name);
2352         mISDNport->b_num = devinfo.nrbchan;
2353         mISDNport->portnum = port;
2354         mISDNport->ntmode = nt;
2355         mISDNport->tespecial = ifport->tespecial;
2356         mISDNport->pri = pri;
2357         mISDNport->ptp = ptp;
2358         mISDNport->l1hold = l1hold;
2359         mISDNport->l2hold = l2hold;
2360         mISDNport->ss5 = ss5;
2361         PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2362         i = 0;
2363         while(i < mISDNport->b_num) {
2364                 mISDNport->b_state[i] = B_STATE_IDLE;
2365                 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2366                 i++;
2367         }
2368
2369         /* if ptp, pull up the link */
2370         if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2371                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2372                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2373                 add_trace("tei", NULL, "%d", 0);
2374                 end_trace();
2375                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2376         }
2377
2378         /* for nt-mode ptmp the link is always up */
2379         if (mISDNport->ntmode && !mISDNport->ptp)
2380                 mISDNport->l2link = 1;
2381
2382         PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2383
2384         start_trace(mISDNport->portnum,
2385                     ifport->interface,
2386                     NULL,
2387                     NULL,
2388                     DIRECTION_NONE,
2389                     CATEGORY_CH,
2390                     0,
2391                     "PORT (open)");
2392         add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2393         add_trace("channels", NULL, "%d", mISDNport->b_num);
2394         if (mISDNport->ss5)
2395                 add_trace("ccitt#5", NULL, "enabled");
2396         end_trace();
2397
2398         return(mISDNport);
2399 }
2400
2401
2402 /*
2403  * load static port instances, if required by mISDNport
2404  */
2405 void mISDNport_static(struct mISDNport *mISDNport)
2406 {
2407         int i;
2408
2409         i = 0;
2410         while(i < mISDNport->b_num) {
2411 #ifdef WITH_SS5
2412                 if (mISDNport->ss5)
2413                         ss5_create_channel(mISDNport, i);
2414 #endif
2415                 i++;
2416         }
2417 }
2418
2419
2420 /*
2421  * function to free ALL cards (ports)
2422  */
2423 void mISDNport_close_all(void)
2424 {
2425         /* free all ports */
2426         while(mISDNport_first)
2427                 mISDNport_close(mISDNport_first);
2428 }
2429
2430 /*
2431  * free only one port
2432  */
2433 void mISDNport_close(struct mISDNport *mISDNport)
2434 {
2435         struct mISDNport **mISDNportp;
2436         class Port *port;
2437         class PmISDN *isdnport;
2438         int i;
2439
2440         /* remove all port instance that are linked to this mISDNport */
2441         again:
2442         port = port_first;
2443         while(port) {
2444                 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2445                         isdnport = (class PmISDN *)port;
2446                         if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2447                                 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2448                                 delete isdnport;
2449                                 goto again;
2450                         }
2451                 }
2452                 port = port->next;
2453         }
2454
2455         /* only if we are already part of interface */
2456         if (mISDNport->ifport) {
2457                 start_trace(mISDNport->portnum,
2458                             mISDNport->ifport->interface,
2459                             NULL,
2460                             NULL,
2461                             DIRECTION_NONE,
2462                             CATEGORY_CH,
2463                             0,
2464                             "PORT (close)");
2465                 end_trace();
2466         }
2467
2468         /* free bchannels */
2469         i = 0;
2470         while(i < mISDNport->b_num) {
2471                 if (mISDNport->b_sock[i].inuse) {
2472                         _bchannel_destroy(mISDNport, i);
2473                         PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2474                 }
2475                 if (mISDNport->b_timer[i].inuse) {
2476                         del_timer(&mISDNport->b_timer[i]);
2477                 }
2478                 i++;
2479         }
2480         del_timer(&mISDNport->l2establish);
2481
2482         /* close layer 3, if open */
2483         if (!mISDNport->gsm && mISDNport->ml3) {
2484                 close_layer3(mISDNport->ml3);
2485         }
2486
2487         /* close gsm socket, if open */
2488         if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2489                 close(mISDNport->lcr_sock);
2490         }
2491
2492         /* purge upqueue */
2493         if (!mISDNport->gsm)
2494                 mqueue_purge(&mISDNport->upqueue);
2495
2496         /* remove from list */
2497         mISDNportp = &mISDNport_first;
2498         while(*mISDNportp) {
2499                 if (*mISDNportp == mISDNport) {
2500                         *mISDNportp = (*mISDNportp)->next;
2501                         mISDNportp = NULL;
2502                         break;
2503                 }
2504                 mISDNportp = &((*mISDNportp)->next);
2505         }
2506
2507         if (mISDNportp)
2508                 FATAL("mISDNport not in list\n");
2509         
2510         FREE(mISDNport, sizeof(struct mISDNport));
2511         pmemuse--;
2512
2513 }
2514
2515
2516 /*
2517  * enque data from upper buffer
2518  */
2519 void PmISDN::txfromup(unsigned char *data, int length)
2520 {
2521         unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2522         struct mISDNhead *hh = (struct mISDNhead *)buf;
2523         int ret;
2524
2525         if (p_m_b_index < 0)
2526                 return;
2527         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2528                 return;
2529
2530         /* check if high priority tones exist
2531          * ignore data in this case
2532          */
2533         if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2534                 return;
2535
2536         /* preload procedure
2537          * if transmit buffer in DSP module is empty,
2538          * preload it to DSP_LOAD to prevent jitter gaps.
2539          */
2540         if (p_m_load == 0 && ISDN_LOAD > 0) {
2541                 hh->prim = PH_DATA_REQ; 
2542                 hh->id = 0;
2543                 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2544                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2545                 if (ret <= 0)
2546                         PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2547                 p_m_load += ISDN_LOAD;
2548                 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2549         }
2550
2551         /* drop if load would exceed ISDN_MAXLOAD
2552          * this keeps the delay not too high
2553          */
2554         if (p_m_load+length > ISDN_MAXLOAD)
2555                 return;
2556
2557         /* make and send frame */
2558         hh->prim = PH_DATA_REQ;
2559         hh->id = 0;
2560         memcpy(buf+MISDN_HEADER_LEN, data, length);
2561         ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2562         if (ret <= 0)
2563                 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2564         p_m_load += length;
2565 }
2566
2567 int PmISDN::inband_send(unsigned char *buffer, int len)
2568 {
2569         PERROR("this function must be derived to function!\n");
2570         return 0;
2571 }
2572
2573 void PmISDN::inband_send_on(void)
2574 {
2575         PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2576         p_m_inband_send_on = 1;
2577         /* trigger inband transmit */
2578         update_load();
2579 }
2580
2581 void PmISDN::inband_send_off(void)
2582 {
2583         PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2584         p_m_inband_send_on = 0;
2585 }
2586
2587 void PmISDN::inband_receive(unsigned char *buffer, int len)
2588 {
2589 //
2590 //      if (len >= SS5_DECODER_NPOINTS)
2591 //              ss5_decode(buffer, SS5_DECODER_NPOINTS);
2592         PERROR("this function must be derived to function!\n");
2593 }
2594
2595 void PmISDN::inband_receive_on(void)
2596 {
2597         /* this must work during constructor, see ss5.cpp */
2598         PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2599         p_m_inband_receive_on = 1;
2600         update_rxoff();
2601 }
2602
2603 void PmISDN::inband_receive_off(void)
2604 {
2605         PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2606         p_m_inband_receive_on = 0;
2607         update_rxoff();
2608 }
2609
2610 void PmISDN::mute_on(void)
2611 {
2612         if (p_m_mute)
2613                 return;
2614         PDEBUG(DEBUG_PORT, "turning mute on.\n");
2615         p_m_mute = 1;
2616         set_conf(p_m_conf, 0);
2617 }
2618
2619 void PmISDN::mute_off(void)
2620 {
2621         if (!p_m_mute)
2622                 return;
2623         PDEBUG(DEBUG_PORT, "turning mute off.\n");
2624         p_m_mute = 0;
2625         set_conf(0, p_m_conf);
2626 }
2627
2628