Replaced polling loop for LCR and chan_lcr with select based event loop.
[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.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         read(fd->fd, &byte, 1);
1838         upqueue_avail = 0;
1839
1840         /* process all ports */
1841         mISDNport = mISDNport_first;
1842         while(mISDNport) {
1843                 /* handle queued up-messages (d-channel) */
1844                 if (!mISDNport->gsm) {
1845                         while ((mb = mdequeue(&mISDNport->upqueue))) {
1846                                 l3m = &mb->l3;
1847                                 switch(l3m->type) {
1848                                         case MPH_ACTIVATE_IND:
1849                                         if (mISDNport->l1link != 1) {
1850                                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1851                                                 end_trace();
1852                                                 mISDNport->l1link = 1;
1853                                         }
1854                                         break;
1855                 
1856                                         case MPH_DEACTIVATE_IND:
1857                                         if (mISDNport->l1link != 0) {
1858                                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1859                                                 end_trace();
1860                                                 mISDNport->l1link = 0;
1861                                         }
1862                                         break;
1863
1864                                         case MPH_INFORMATION_IND:
1865                                         PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1866                                         switch (l3m->pid) {
1867                                                 case L1_SIGNAL_LOS_ON:
1868                                                 mISDNport->los = 1;
1869                                                 break;
1870                                                 case L1_SIGNAL_LOS_OFF:
1871                                                 mISDNport->los = 0;
1872                                                 break;
1873                                                 case L1_SIGNAL_AIS_ON:
1874                                                 mISDNport->ais = 1;
1875                                                 break;
1876                                                 case L1_SIGNAL_AIS_OFF:
1877                                                 mISDNport->ais = 0;
1878                                                 break;
1879                                                 case L1_SIGNAL_RDI_ON:
1880                                                 mISDNport->rdi = 1;
1881                                                 break;
1882                                                 case L1_SIGNAL_RDI_OFF:
1883                                                 mISDNport->rdi = 0;
1884                                                 break;
1885                                                 case L1_SIGNAL_SLIP_TX:
1886                                                 mISDNport->slip_tx++;
1887                                                 break;
1888                                                 case L1_SIGNAL_SLIP_RX:
1889                                                 mISDNport->slip_rx++;
1890                                                 break;
1891                                         }
1892                                         break;
1893
1894                                         case MT_L2ESTABLISH:
1895                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1896                                         add_trace("tei", NULL, "%d", l3m->pid);
1897                                         end_trace();
1898                                         mISDNport->l2link = 1;
1899                                         if (l3m->pid < 128)
1900                                                 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1901                                         if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1902                                                 if (mISDNport->l2establish.active) {
1903                                                         unsched_timer(&mISDNport->l2establish);
1904                                                         PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1905                                                 }
1906                                         }
1907                                         break;
1908
1909                                         case MT_L2RELEASE:
1910                                         if (l3m->pid < 128)
1911                                                 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1912                                         if (!mISDNport->l2establish.active) {
1913                                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1914                                                 add_trace("tei", NULL, "%d", l3m->pid);
1915                                                 end_trace();
1916                                                 /* down if not nt-ptmp */ 
1917                                                 if (!mISDNport->ntmode || mISDNport->ptp)
1918                                                         mISDNport->l2link = 0;
1919                                         }
1920                                         if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1921                                                 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1922                                                         PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1923                                                         schedule_timer(&mISDNport->l2establish, 5, 0);
1924                                                         mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1925                                                 }
1926                                         }
1927                                         break;
1928
1929                                         default:
1930                                         /* l3-data is sent to LCR */
1931                                         stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1932                                 }
1933                                 /* free message */
1934                                 free_l3_msg(l3m);
1935                         }
1936                 }
1937                 mISDNport = mISDNport->next;
1938         }
1939         return 0;
1940 }
1941
1942 /* l2 establish timer fires */
1943 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1944 {
1945         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1946
1947         if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1948 //              PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1949                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1950                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1951         }
1952
1953         return 0;
1954 }
1955
1956 /* handle frames from bchannel */
1957 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1958 {
1959         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1960         unsigned char buffer[2048+MISDN_HEADER_LEN];
1961         struct mISDNhead *hh = (struct mISDNhead *)buffer;
1962         int ret;
1963
1964         ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1965         if (ret < 0) {
1966                 PERROR("read error frame, errno %d\n", errno);
1967                 return 0;
1968         }
1969         if (ret < (int)MISDN_HEADER_LEN) {
1970                 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1971                 return 0;
1972         }
1973         switch(hh->prim) {
1974                 /* we don't care about confirms, we use rx data to sync tx */
1975                 case PH_DATA_CNF:
1976                 break;
1977
1978                 /* we receive audio data, we respond to it AND we send tones */
1979                 case PH_DATA_IND:
1980                 case DL_DATA_IND:
1981                 case PH_DATA_REQ:
1982                 case DL_DATA_REQ:
1983                 case PH_CONTROL_IND:
1984                 if (mISDNport->b_port[i])
1985                         mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1986                 else
1987                         PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1988                 break;
1989
1990                 case PH_ACTIVATE_IND:
1991                 case DL_ESTABLISH_IND:
1992                 case PH_ACTIVATE_CNF:
1993                 case DL_ESTABLISH_CNF:
1994                 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1995                 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1996                 break;
1997
1998                 case PH_DEACTIVATE_IND:
1999                 case DL_RELEASE_IND:
2000                 case PH_DEACTIVATE_CNF:
2001                 case DL_RELEASE_CNF:
2002                 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2003                 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2004                 break;
2005
2006                 default:
2007                 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2008         }
2009
2010         return 0;
2011 }
2012
2013 /* process timer events for bchannel handling */
2014 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2015 {
2016         struct mISDNport *mISDNport = (struct mISDNport *)instance;
2017 puts("fires");
2018
2019         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2020
2021         return 0;
2022 }
2023
2024
2025 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2026 {
2027         /* IMPORTAINT:
2028          *
2029          * l3m must be queued, except for MT_ASSIGN
2030          *
2031          */
2032         struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2033         struct mbuffer *mb;
2034
2035         /* special MT_ASSIGN handling:
2036          *
2037          * if we request a PID from mlayer, we always do it while lcr is locked.
2038          * therefore we must check the MT_ASSIGN reply first before we lock.
2039          * this is because the MT_ASSIGN reply is received with the requesting
2040          * process, not by the mlayer thread!
2041          * this means, that the reply is sent during call of the request.
2042          * we must check if we get a reply and we know that we lcr is currently
2043          * locked.
2044          */
2045         if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2046                 /* let's do some checking if someone changes stack behaviour */
2047                 if (mt_assign_pid != 0)
2048                         FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2049                 mt_assign_pid = pid;
2050                 return(0);
2051         }
2052         /* queue message, create, if required */
2053         if (!l3m) {
2054                 l3m = alloc_l3_msg();
2055                 if (!l3m)
2056                         FATAL("No memory for layer 3 message\n");
2057         }
2058         mb = container_of(l3m, struct mbuffer, l3);
2059         l3m->type = cmd;
2060         l3m->pid = pid;
2061         mqueue_tail(&mISDNport->upqueue, mb);
2062         if (!upqueue_avail) {
2063                 upqueue_avail = 1;
2064                 char byte = 0;
2065                 write(upqueue_pipe[1], &byte, 1);
2066         }
2067         return 0;
2068 }
2069
2070 int mISDN_getportbyname(int sock, int cnt, char *portname)
2071 {
2072         struct mISDN_devinfo devinfo;
2073         int port = 0, ret;
2074
2075         /* resolve name */
2076         while (port < cnt) {
2077                 devinfo.id = port;
2078                 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2079                 if (ret < 0)
2080                         return ret;
2081                 if (!strcasecmp(devinfo.name, portname))
2082                         break;
2083                 port++;
2084         }
2085         if (port == cnt)
2086                 return -EIO;
2087
2088         return (port);
2089 }
2090
2091 /*
2092  * global function to add a new card (port)
2093  */
2094 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2095 {
2096         int ret;
2097         struct mISDNport *mISDNport, **mISDNportp;
2098         int port = ifport->portnum;
2099         int ptp = ifport->ptp;
2100         int force_nt = ifport->nt;
2101         int l1hold = ifport->l1hold;
2102         int l2hold = ifport->l2hold;
2103         int gsm = ifport->gsm;
2104         int ss5 = ifport->ss5;
2105         int i, cnt;
2106         int pri, bri, pots;
2107         int nt, te;
2108 //      struct mlayer3 *ml3;
2109         struct mISDN_devinfo devinfo;
2110         unsigned int protocol, prop;
2111
2112         /* check port counts */
2113         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2114         if (ret < 0) {
2115                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2116                 return(NULL);
2117         }
2118
2119         if (cnt <= 0) {
2120                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2121                 return(NULL);
2122         }
2123         if (port < 0) {
2124                 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2125                 if (port < 0) {
2126                         if (gsm)
2127                                 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
2128                         else
2129                                 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2130                         return(NULL);
2131                 }
2132                 // note: 'port' has still the port number
2133         }
2134         if (port>cnt || port<0) {
2135                 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2136                 return(NULL);
2137         }
2138
2139         /* get port attributes */
2140         pri = bri = pots = nt = te = 0;
2141         devinfo.id = port;
2142         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2143         if (ret < 0) {
2144                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2145                 return(NULL);
2146         }
2147         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2148                 bri = 1;
2149                 te = 1;
2150         }
2151         if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2152                 bri = 1;
2153                 nt = 1;
2154         }
2155         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2156                 pri = 1;
2157                 te = 1;
2158         }
2159         if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2160                 pri = 1;
2161                 nt = 1;
2162         }
2163 #ifdef ISDN_P_FXS
2164         if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2165                 pots = 1;
2166                 te = 1;
2167         }
2168 #endif
2169 #ifdef ISDN_P_FXO
2170         if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2171                 pots = 1;
2172                 nt = 1;
2173         }
2174 #endif
2175         if (force_nt && !nt) {
2176                 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2177                 return(NULL);
2178         }
2179         if (bri && pri) {
2180                 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2181                 return(NULL);
2182         }
2183         if (pots && !bri && !pri) {
2184                 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2185                 return(NULL);
2186         }
2187         if (!bri && !pri) {
2188                 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2189                 return(NULL);
2190         }
2191         if (!nt && !te) {
2192                 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2193                 return(NULL);
2194         }
2195         /* set NT by turning off TE */
2196         if (force_nt && nt)
2197                 te = 0;
2198         /* if TE an NT is supported (and not forced to NT), turn off NT */
2199         if (te && nt)
2200                 nt = 0;
2201
2202         /* check for double use of port */
2203         if (nt) {
2204                 mISDNport = mISDNport_first;
2205                 while(mISDNport) {
2206                         if (mISDNport->portnum == port)
2207                                 break;
2208                         mISDNport = mISDNport->next;
2209                 }
2210                 if (mISDNport) {
2211                         PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2212                         return(NULL);
2213                 }
2214         }
2215
2216         /* check for continous channelmap with no bchannel on slot 16 */
2217         if (test_channelmap(0, devinfo.channelmap)) {
2218                 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2219                 return(NULL);
2220         }
2221         i = 1;
2222         while(i < (int)devinfo.nrbchan + 1) {
2223                 if (i == 16) {
2224                         if (test_channelmap(i, devinfo.channelmap)) {
2225                                 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2226                                 return(NULL);
2227                         }
2228                 } else {
2229                         if (!test_channelmap(i, devinfo.channelmap)) {
2230                                 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2231                                 return(NULL);
2232                         }
2233                 }
2234                 i++;
2235         }
2236
2237         /* add mISDNport structure */
2238         mISDNportp = &mISDNport_first;
2239         while(*mISDNportp)
2240                 mISDNportp = &((*mISDNportp)->next);
2241         mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2242         add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2243         if (gsm | ss5) {
2244                 /* gsm/ss5 link is always active */
2245                 mISDNport->l1link = 1;
2246                 mISDNport->l2link = 1;
2247         } else {
2248                 mISDNport->l1link = -1;
2249                 mISDNport->l2link = -1;
2250         }
2251         mISDNport->gsm = gsm;
2252         pmemuse++;
2253         *mISDNportp = mISDNport;
2254
2255         /* if pri, must set PTP */
2256         if (pri)
2257                 ptp = 1;
2258
2259         /* set ss5 params */
2260         if (ss5) {
2261                 /* try to keep interface enabled */
2262                 l1hold = 1;
2263                 l2hold = 1;
2264         }
2265         /* set l2hold */
2266         switch (l2hold) {
2267                 case -1: // off
2268                 l2hold = 0;
2269                 break;
2270                 case 1: // on
2271                 l2hold = 1;
2272                 break;
2273                 default:
2274                 if (ptp)
2275                         l2hold = 1;
2276                 else
2277                         l2hold = 0;
2278                 break;
2279         }
2280                 
2281         /* allocate ressources of port */
2282         protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2283         prop = (1 << MISDN_FLG_L2_CLEAN);
2284         if (ptp) // ptp forced
2285                prop |= (1 << MISDN_FLG_PTP);
2286         if (nt) // supports hold/retrieve on nt-mode
2287                prop |= (1 << MISDN_FLG_NET_HOLD);
2288         if (l1hold) // supports layer 1 hold
2289                prop |= (1 << MISDN_FLG_L1_HOLD);
2290         if (l2hold) // supports layer 2 hold
2291                prop |= (1 << MISDN_FLG_L2_HOLD);
2292         /* open layer 3 and init upqueue */
2293         if (gsm) {
2294                 unsigned long on = 1;
2295                 struct sockaddr_mISDN addr;
2296
2297                 if (devinfo.nrbchan < 8) {
2298                         PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2299                         mISDNport_close(mISDNport);
2300                         return(NULL);
2301                 }
2302
2303                 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2304                         PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2305                         mISDNport_close(mISDNport);
2306                         return(NULL);
2307                 }
2308                 /* set nonblocking io */
2309                 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2310                         PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2311                         mISDNport_close(mISDNport);
2312                         return(NULL);
2313                 }
2314                 /* bind socket to dchannel */
2315                 memset(&addr, 0, sizeof(addr));
2316                 addr.family = AF_ISDN;
2317                 addr.dev = port;
2318                 addr.channel = 0;
2319                 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2320                         PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2321                         mISDNport_close(mISDNport);
2322                         return(NULL);
2323                 }
2324         } else {
2325                 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2326                 mqueue_init(&mISDNport->upqueue);
2327                 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2328                 if (!mISDNport->ml3) {
2329                         mqueue_purge(&mISDNport->upqueue);
2330                         PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2331                         start_trace(port,
2332                                 ifport->interface,
2333                                 NULL,
2334                                 NULL,
2335                                 DIRECTION_NONE,
2336                                 CATEGORY_CH,
2337                                 0,
2338                                 "PORT (open failed)");
2339                         end_trace();
2340                         mISDNport_close(mISDNport);
2341                         return(NULL);
2342                 }
2343         }
2344
2345         SCPY(mISDNport->name, devinfo.name);
2346         mISDNport->b_num = devinfo.nrbchan;
2347         mISDNport->portnum = port;
2348         mISDNport->ntmode = nt;
2349         mISDNport->tespecial = ifport->tespecial;
2350         mISDNport->pri = pri;
2351         mISDNport->ptp = ptp;
2352         mISDNport->l1hold = l1hold;
2353         mISDNport->l2hold = l2hold;
2354         mISDNport->ss5 = ss5;
2355         PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2356         i = 0;
2357         while(i < mISDNport->b_num) {
2358                 mISDNport->b_state[i] = B_STATE_IDLE;
2359                 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2360                 i++;
2361         }
2362
2363         /* if ptp, pull up the link */
2364         if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2365                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2366                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2367                 add_trace("tei", NULL, "%d", 0);
2368                 end_trace();
2369                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2370         }
2371
2372         /* for nt-mode ptmp the link is always up */
2373         if (mISDNport->ntmode && !mISDNport->ptp)
2374                 mISDNport->l2link = 1;
2375
2376         PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2377
2378         start_trace(mISDNport->portnum,
2379                     ifport->interface,
2380                     NULL,
2381                     NULL,
2382                     DIRECTION_NONE,
2383                     CATEGORY_CH,
2384                     0,
2385                     "PORT (open)");
2386         add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2387         add_trace("channels", NULL, "%d", mISDNport->b_num);
2388         if (mISDNport->ss5)
2389                 add_trace("ccitt#5", NULL, "enabled");
2390         end_trace();
2391
2392         return(mISDNport);
2393 }
2394
2395
2396 /*
2397  * load static port instances, if required by mISDNport
2398  */
2399 void mISDNport_static(struct mISDNport *mISDNport)
2400 {
2401         int i;
2402
2403         i = 0;
2404         while(i < mISDNport->b_num) {
2405 #ifdef WITH_SS5
2406                 if (mISDNport->ss5)
2407                         ss5_create_channel(mISDNport, i);
2408 #endif
2409                 i++;
2410         }
2411 }
2412
2413
2414 /*
2415  * function to free ALL cards (ports)
2416  */
2417 void mISDNport_close_all(void)
2418 {
2419         /* free all ports */
2420         while(mISDNport_first)
2421                 mISDNport_close(mISDNport_first);
2422 }
2423
2424 /*
2425  * free only one port
2426  */
2427 void mISDNport_close(struct mISDNport *mISDNport)
2428 {
2429         struct mISDNport **mISDNportp;
2430         class Port *port;
2431         class PmISDN *isdnport;
2432         int i;
2433
2434         /* remove all port instance that are linked to this mISDNport */
2435         again:
2436         port = port_first;
2437         while(port) {
2438                 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2439                         isdnport = (class PmISDN *)port;
2440                         if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2441                                 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2442                                 delete isdnport;
2443                                 goto again;
2444                         }
2445                 }
2446                 port = port->next;
2447         }
2448
2449         /* only if we are already part of interface */
2450         if (mISDNport->ifport) {
2451                 start_trace(mISDNport->portnum,
2452                             mISDNport->ifport->interface,
2453                             NULL,
2454                             NULL,
2455                             DIRECTION_NONE,
2456                             CATEGORY_CH,
2457                             0,
2458                             "PORT (close)");
2459                 end_trace();
2460         }
2461
2462         /* free bchannels */
2463         i = 0;
2464         while(i < mISDNport->b_num) {
2465                 if (mISDNport->b_sock[i].inuse) {
2466                         _bchannel_destroy(mISDNport, i);
2467                         PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2468                 }
2469                 if (mISDNport->b_timer[i].inuse) {
2470                         del_timer(&mISDNport->b_timer[i]);
2471                 }
2472                 i++;
2473         }
2474         del_timer(&mISDNport->l2establish);
2475
2476         /* close layer 3, if open */
2477         if (!mISDNport->gsm && mISDNport->ml3) {
2478                 close_layer3(mISDNport->ml3);
2479         }
2480
2481         /* close gsm socket, if open */
2482         if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2483                 close(mISDNport->lcr_sock);
2484         }
2485
2486         /* purge upqueue */
2487         if (!mISDNport->gsm)
2488                 mqueue_purge(&mISDNport->upqueue);
2489
2490         /* remove from list */
2491         mISDNportp = &mISDNport_first;
2492         while(*mISDNportp) {
2493                 if (*mISDNportp == mISDNport) {
2494                         *mISDNportp = (*mISDNportp)->next;
2495                         mISDNportp = NULL;
2496                         break;
2497                 }
2498                 mISDNportp = &((*mISDNportp)->next);
2499         }
2500
2501         if (mISDNportp)
2502                 FATAL("mISDNport not in list\n");
2503         
2504         FREE(mISDNport, sizeof(struct mISDNport));
2505         pmemuse--;
2506
2507 }
2508
2509
2510 /*
2511  * enque data from upper buffer
2512  */
2513 void PmISDN::txfromup(unsigned char *data, int length)
2514 {
2515         unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2516         struct mISDNhead *hh = (struct mISDNhead *)buf;
2517         int ret;
2518
2519         if (p_m_b_index < 0)
2520                 return;
2521         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2522                 return;
2523
2524         /* check if high priority tones exist
2525          * ignore data in this case
2526          */
2527         if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2528                 return;
2529
2530         /* preload procedure
2531          * if transmit buffer in DSP module is empty,
2532          * preload it to DSP_LOAD to prevent jitter gaps.
2533          */
2534         if (p_m_load == 0 && ISDN_LOAD > 0) {
2535                 hh->prim = PH_DATA_REQ; 
2536                 hh->id = 0;
2537                 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2538                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2539                 if (ret <= 0)
2540                         PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2541                 p_m_load += ISDN_LOAD;
2542                 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2543         }
2544
2545         /* drop if load would exceed ISDN_MAXLOAD
2546          * this keeps the delay not too high
2547          */
2548         if (p_m_load+length > ISDN_MAXLOAD)
2549                 return;
2550
2551         /* make and send frame */
2552         hh->prim = PH_DATA_REQ;
2553         hh->id = 0;
2554         memcpy(buf+MISDN_HEADER_LEN, data, length);
2555         ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2556         if (ret <= 0)
2557                 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2558         p_m_load += length;
2559 }
2560
2561 int PmISDN::inband_send(unsigned char *buffer, int len)
2562 {
2563         PERROR("this function must be derived to function!\n");
2564         return 0;
2565 }
2566
2567 void PmISDN::inband_send_on(void)
2568 {
2569         PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2570         p_m_inband_send_on = 1;
2571         /* trigger inband transmit */
2572         update_load();
2573 }
2574
2575 void PmISDN::inband_send_off(void)
2576 {
2577         PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2578         p_m_inband_send_on = 0;
2579 }
2580
2581 void PmISDN::inband_receive(unsigned char *buffer, int len)
2582 {
2583 //
2584 //      if (len >= SS5_DECODER_NPOINTS)
2585 //              ss5_decode(buffer, SS5_DECODER_NPOINTS);
2586         PERROR("this function must be derived to function!\n");
2587 }
2588
2589 void PmISDN::inband_receive_on(void)
2590 {
2591         /* this must work during constructor, see ss5.cpp */
2592         PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2593         p_m_inband_receive_on = 1;
2594         update_rxoff();
2595 }
2596
2597 void PmISDN::inband_receive_off(void)
2598 {
2599         PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2600         p_m_inband_receive_on = 0;
2601         update_rxoff();
2602 }
2603
2604 void PmISDN::mute_on(void)
2605 {
2606         if (p_m_mute)
2607                 return;
2608         PDEBUG(DEBUG_PORT, "turning mute on.\n");
2609         p_m_mute = 1;
2610         set_conf(p_m_conf, 0);
2611 }
2612
2613 void PmISDN::mute_off(void)
2614 {
2615         if (!p_m_mute)
2616                 return;
2617         PDEBUG(DEBUG_PORT, "turning mute off.\n");
2618         p_m_mute = 0;
2619         set_conf(0, p_m_conf);
2620 }
2621
2622