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