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