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