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