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