[gsm] Make LCR work with current Osmocom-BB.
[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                         if (!p_m_dtmf)
1371                                 add_trace("info", NULL, "DTMF is disabled");
1372                         end_trace();
1373                         if (!p_m_dtmf)
1374                                 return;
1375                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1376                         message->param.dtmf = cont & DTMF_TONE_MASK;
1377                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  DTMF digit '%c'\n", p_name, message->param.dtmf);
1378                         message_put(message);
1379                         return;
1380                 }
1381                 switch(cont) {
1382                         case DSP_BF_REJECT:
1383                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1384                         add_trace("DSP-CRYPT", NULL, "error");
1385                         end_trace();
1386                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1387                         message->param.crypt.type = CC_ERROR_IND;
1388                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  reject of blowfish.\n", p_name);
1389                         message_put(message);
1390                         break;
1391
1392                         case DSP_BF_ACCEPT:
1393                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1394                         add_trace("DSP-CRYPT", NULL, "ok");
1395                         end_trace();
1396                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1397                         message->param.crypt.type = CC_ACTBF_CONF;
1398                         PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION  accept of blowfish.\n", p_name);
1399                         message_put(message);
1400                         break;
1401
1402                         default:
1403                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1404                         add_trace("unknown", NULL, "0x%x", cont);
1405                         end_trace();
1406                 }
1407                 return;
1408         }
1409         if (hh->prim == PH_CONTROL_IND) {
1410                 switch(hh->id) {
1411                         default:
1412                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1413                         add_trace("unknown", NULL, "0x%x", hh->id);
1414                         end_trace();
1415                 }
1416                 return;
1417         }
1418         if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1419                 if (!p_m_txdata) {
1420                         /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1421                         PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1422                         return;
1423                 }
1424                 /* see below (same condition) */
1425                 if (p_state!=PORT_STATE_CONNECT
1426                          && !p_m_mISDNport->tones)
1427                         return;
1428 //              printf(".");fflush(stdout);return;
1429                 if (p_record)
1430                         record(data, len, 1); // from up
1431                 return;
1432         }
1433         if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1434                 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1435                 return;
1436         }
1437
1438         /* inband is processed */
1439         if (p_m_inband_receive_on)
1440                 inband_receive(data, len);
1441
1442         /* calls will not process any audio data unless
1443          * the call is connected OR tones feature is enabled.
1444          */
1445 #ifndef DEBUG_COREBRIDGE
1446         if (p_state!=PORT_STATE_CONNECT
1447          && !p_m_mISDNport->tones)
1448                 return;
1449 #endif
1450
1451 #if 0
1452         /* the bearer capability must be audio in order to send and receive
1453          * audio prior or after connect.
1454          */
1455         if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1456                 return;
1457 #endif
1458
1459         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1460         if (p_m_rxoff) {
1461                 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1462                 return;
1463         }
1464
1465         /* record data */
1466         if (p_record)
1467                 record(data, len, 0); // from down
1468
1469         /* randomize and listen to crypt message if enabled */
1470         if (p_m_crypt_listen) {
1471                 /* the noisy randomizer */
1472                 p = data;
1473                 l = len;
1474                 while(l--)
1475                         mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1476
1477                 cryptman_listen_bch(data, len);
1478         }
1479
1480         p = data;
1481
1482         /* send data to epoint */
1483         if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1484                 length_temp = len;
1485                 data_temp = p;
1486                 while(length_temp) {
1487                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1488                         message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1489                         memcpy(message->param.data.data, data_temp, message->param.data.len);
1490                         message_put(message);
1491                         if (length_temp <= sizeof(message->param.data.data))
1492                                 break;
1493                         data_temp += sizeof(message->param.data.data);
1494                         length_temp -= sizeof(message->param.data.data);
1495                 }
1496         }
1497 }
1498
1499
1500 /*
1501  * set echotest
1502  */
1503 void PmISDN::set_echotest(int echo)
1504 {
1505         if (p_m_echo != echo) {
1506                 p_m_echo = echo;
1507                 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1508                 if (p_m_b_channel)
1509                         if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1510                                 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);
1511         }
1512 }
1513
1514 /*
1515  * set tone
1516  */
1517 void PmISDN::set_tone(const char *dir, const char *tone)
1518 {
1519         int id = TONE_OFF;
1520         int dsp = DSP_NONE;
1521
1522         /* if no directory is given (by extension), we use interface.conf or options.conf */
1523         if (!dir || !dir[0]) {
1524                 if (p_m_mISDNport->ifport->tones_dir[0])
1525                         dir = p_m_mISDNport->ifport->tones_dir;
1526                 else if (options.tones_dir[0])
1527                         dir = options.tones_dir;
1528         }
1529
1530         if (!tone)
1531                 tone = "";
1532         PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1533         if (!tone[0]) {
1534                 id = TONE_OFF;
1535                 goto setdsp;
1536         }
1537
1538         /* check for dsp tones */
1539         if (!strcmp(dir, "american"))
1540                 dsp = DSP_AMERICAN;
1541         if (!strcmp(dir, "german"))
1542                 dsp = DSP_GERMAN;
1543         if (!strcmp(dir, "oldgerman"))
1544                 dsp = DSP_OLDGERMAN;
1545
1546         /* check if we NOT really have to use a dsp-tone */
1547         if (dsp == DSP_NONE) {
1548                 nodsp:
1549                 if (p_m_tone)
1550                 if (p_m_b_index > -1)
1551                 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) {
1552                         PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1553                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1554                 }
1555                 p_m_tone = 0;
1556                 Port::set_tone(dir, tone);
1557                 return;
1558         }
1559
1560         /* now we USE dsp-tone, convert name */
1561         if (!strcmp(tone, "dialtone")) {
1562                 switch(dsp) {
1563                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1564                 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1565                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1566                 }
1567         } else if (!strcmp(tone, "dialpbx")) {
1568                 switch(dsp) {
1569                 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1570                 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1571                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1572                 }
1573         } else if (!strcmp(tone, "ringing")) {
1574                 switch(dsp) {
1575                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1576                 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1577                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1578                 }
1579         } else if (!strcmp(tone, "ringpbx")) {
1580                 switch(dsp) {
1581                 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1582                 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1583                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1584                 }
1585         } else if (!strcmp(tone, "busy")) {
1586                 busy:
1587                 switch(dsp) {
1588                 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1589                 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1590                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1591                 }
1592         } else if (!strcmp(tone, "release")) {
1593                 hangup:
1594                 switch(dsp) {
1595                 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1596                 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1597                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1598                 }
1599         } else if (!strcmp(tone, "cause_10"))
1600                 goto hangup;
1601         else if (!strcmp(tone, "cause_11"))
1602                 goto busy;
1603         else if (!strcmp(tone, "cause_22")) {
1604                 switch(dsp) {
1605                 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1606                 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1607                 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1608                 }
1609         } else if (!strncmp(tone, "cause_", 6))
1610                 id = TONE_SPECIAL_INFO;
1611         else
1612                 id = TONE_OFF;
1613
1614         /* if we have a tone that is not supported by dsp */
1615         if (id==TONE_OFF && tone[0])
1616                 goto nodsp;
1617
1618         setdsp:
1619         if (p_m_tone != id) {
1620                 /* set new tone */
1621                 p_m_tone = id;
1622                 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1623                 if (p_m_b_index > -1)
1624                 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)
1625                         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);
1626         }
1627         /* turn user-space tones off in cases of no tone OR dsp tone */
1628         Port::set_tone("",NULL);
1629 }
1630
1631
1632 /* MESSAGE_mISDNSIGNAL */
1633 //extern struct lcr_msg *dddebug;
1634 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1635 {
1636         int oldconf, newconf;
1637         switch(param->mISDNsignal.message) {
1638                 case mISDNSIGNAL_VOLUME:
1639                 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1640                         p_m_tx_gain = param->mISDNsignal.tx_gain;
1641                         PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1642                         if (p_m_b_index > -1)
1643                         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)
1644                                 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);
1645                 } else
1646                         PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1647                 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1648                         p_m_rx_gain = param->mISDNsignal.rx_gain;
1649                         PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1650                         if (p_m_b_index > -1)
1651                         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)
1652                                 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);
1653                 } else
1654                         PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1655                 break;
1656
1657                 case mISDNSIGNAL_CONF:
1658                 oldconf = p_m_mute?0:p_m_conf;
1659                 p_m_conf = param->mISDNsignal.conf;
1660                 newconf = p_m_mute?0:p_m_conf;
1661                 set_conf(oldconf, newconf);
1662                 break;
1663
1664                 case mISDNSIGNAL_JOINDATA:
1665                 if (p_m_joindata != param->mISDNsignal.joindata) {
1666                         p_m_joindata = param->mISDNsignal.joindata;
1667                         PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1668                         update_rxoff();
1669                 } else
1670                         PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1671                 break;
1672                 
1673                 case mISDNSIGNAL_DELAY:
1674                 if (p_m_delay != param->mISDNsignal.delay) {
1675                         p_m_delay = param->mISDNsignal.delay;
1676                         PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1677                         if (p_m_b_index > -1)
1678                         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)
1679                                 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);
1680                 } else
1681                         PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1682                 break;
1683
1684                 default:
1685                 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1686         }
1687 }
1688
1689 /* MESSAGE_CRYPT */
1690 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1691 {
1692         struct lcr_msg *message;
1693
1694         switch(param->crypt.type) {
1695                 case CC_ACTBF_REQ:           /* activate blowfish */
1696                 p_m_crypt = 1;
1697                 p_m_crypt_key_len = param->crypt.len;
1698                 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1699                         PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1700                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1701                         message->param.crypt.type = CC_ERROR_IND;
1702                         message_put(message);
1703                         break;
1704                 }
1705                 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1706                 crypt_off:
1707                 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1708                 if (p_m_b_index > -1)
1709                 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)
1710                         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);
1711                 break;
1712
1713                 case CC_DACT_REQ:            /* deactivate session encryption */
1714                 p_m_crypt = 0;
1715                 goto crypt_off;
1716                 break;
1717
1718                 case CR_LISTEN_REQ:          /* start listening to messages */
1719                 p_m_crypt_listen = 1;
1720                 update_rxoff();
1721                 p_m_crypt_listen_state = 0;
1722                 break;
1723
1724                 case CR_UNLISTEN_REQ:        /* stop listening to messages */
1725                 p_m_crypt_listen = 0;
1726                 update_rxoff();
1727                 break;
1728
1729                 case CR_MESSAGE_REQ:         /* send message */
1730                 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1731                 if (!p_m_crypt_msg_len) {
1732                         PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1733                         break;
1734                 }
1735                 p_m_crypt_msg_current = 0; /* reset */
1736                 p_m_crypt_msg_loops = 6; /* enable */
1737                 update_rxoff();
1738                 update_load();
1739 #if 0
1740                 /* disable txmix, or we get corrupt data due to audio process */
1741                 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1742                         PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1743                         ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1744                 }
1745 #endif
1746                 break;
1747
1748                 default:
1749                 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1750         }
1751
1752 }
1753
1754 /*
1755  * endpoint sends messages to the port
1756  */
1757 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1758 {
1759         if (Port::message_epoint(epoint_id, message_id, param))
1760                 return(1);
1761
1762         switch(message_id) {
1763                 case MESSAGE_DATA: /* tx-data from upper layer */
1764                 txfromup(param->data.data, param->data.len);
1765                 return(1);
1766
1767                 case MESSAGE_mISDNSIGNAL: /* user command */
1768                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1769                 message_mISDNsignal(epoint_id, message_id, param);
1770                 return(1);
1771
1772                 case MESSAGE_CRYPT: /* crypt control command */
1773                 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1774                 message_crypt(epoint_id, message_id, param);
1775                 return(1);
1776         }
1777
1778         return(0);
1779 }
1780
1781 void PmISDN::update_rxoff(void)
1782 {
1783         /* call bridges in user space OR crypto OR recording */
1784         if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1785                 /* rx IS required */
1786                 if (p_m_rxoff) {
1787                         /* turn on RX */
1788                         p_m_rxoff = 0;
1789                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1790                         if (p_m_b_index > -1)
1791                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1792                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1793                 }
1794         } else {
1795                 /* rx NOT required */
1796                 if (!p_m_rxoff) {
1797                         /* turn off RX */
1798                         p_m_rxoff = 1;
1799                         PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1800                         if (p_m_b_index > -1)
1801                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1802                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1803                 }
1804         }
1805         /* recording */
1806         if (p_record) {
1807                 /* txdata IS required */
1808                 if (!p_m_txdata) {
1809                         /* turn on RX */
1810                         p_m_txdata = 1;
1811                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1812                         if (p_m_b_index > -1)
1813                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1814                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1815                 }
1816         } else {
1817                 /* txdata NOT required */
1818                 if (p_m_txdata) {
1819                         /* turn off RX */
1820                         p_m_txdata = 0;
1821                         PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1822                         if (p_m_b_index > -1)
1823                                 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1824                                         ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1825                 }
1826         }
1827 }
1828
1829 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1830 {
1831         struct mISDNport *mISDNport;
1832         struct mbuffer *mb;
1833         struct l3_msg *l3m;
1834         char byte;
1835         int ret;
1836
1837         /* unset global semaphore */
1838         upqueue_avail = 0;
1839         // with a very small incident, upqueue_avail may be set by mISDN thread and
1840         // another byte may be sent to the pipe, which causes a call to this function
1841         // again with nothing in the upqueue. this is no problem.
1842         ret = read(fd->fd, &byte, 1);
1843
1844         /* process all ports */
1845         mISDNport = mISDNport_first;
1846         while(mISDNport) {
1847                 /* handle queued up-messages (d-channel) */
1848                 if (!mISDNport->isloopback) {
1849                         while ((mb = mdequeue(&mISDNport->upqueue))) {
1850                                 l3m = &mb->l3;
1851                                 switch(l3m->type) {
1852                                         case MPH_ACTIVATE_IND:
1853                                         if (mISDNport->l1link != 1) {
1854                                                 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1855                                                 end_trace();
1856                                                 mISDNport->l1link = 1;
1857                                         }
1858                                         break;
1859                 
1860                                         case MPH_DEACTIVATE_IND:
1861                                         if (mISDNport->l1link != 0) {
1862                                                 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1863                                                 end_trace();
1864                                                 mISDNport->l1link = 0;
1865                                         }
1866                                         break;
1867
1868                                         case MPH_INFORMATION_IND:
1869                                         PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1870                                         switch (l3m->pid) {
1871                                                 case L1_SIGNAL_LOS_ON:
1872                                                 mISDNport->los = 1;
1873                                                 break;
1874                                                 case L1_SIGNAL_LOS_OFF:
1875                                                 mISDNport->los = 0;
1876                                                 break;
1877                                                 case L1_SIGNAL_AIS_ON:
1878                                                 mISDNport->ais = 1;
1879                                                 break;
1880                                                 case L1_SIGNAL_AIS_OFF:
1881                                                 mISDNport->ais = 0;
1882                                                 break;
1883                                                 case L1_SIGNAL_RDI_ON:
1884                                                 mISDNport->rdi = 1;
1885                                                 break;
1886                                                 case L1_SIGNAL_RDI_OFF:
1887                                                 mISDNport->rdi = 0;
1888                                                 break;
1889                                                 case L1_SIGNAL_SLIP_TX:
1890                                                 mISDNport->slip_tx++;
1891                                                 break;
1892                                                 case L1_SIGNAL_SLIP_RX:
1893                                                 mISDNport->slip_rx++;
1894                                                 break;
1895                                         }
1896                                         break;
1897
1898                                         case MT_L2ESTABLISH:
1899                                         l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1900                                         add_trace("tei", NULL, "%d", l3m->pid);
1901                                         end_trace();
1902                                         mISDNport->l2link = 1;
1903                                         if (l3m->pid < 128)
1904                                                 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1905                                         if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1906                                                 if (mISDNport->l2establish.active) {
1907                                                         unsched_timer(&mISDNport->l2establish);
1908                                                         PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1909                                                 }
1910                                         }
1911                                         break;
1912
1913                                         case MT_L2RELEASE:
1914                                         if (l3m->pid < 128)
1915                                                 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1916                                         if (!mISDNport->l2establish.active) {
1917                                                 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1918                                                 add_trace("tei", NULL, "%d", l3m->pid);
1919                                                 end_trace();
1920                                                 /* down if not nt-ptmp */ 
1921                                                 if (!mISDNport->ntmode || mISDNport->ptp)
1922                                                         mISDNport->l2link = 0;
1923                                         }
1924                                         if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1925                                                 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1926                                                         PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1927                                                         schedule_timer(&mISDNport->l2establish, 5, 0);
1928                                                         mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1929                                                 }
1930                                         }
1931                                         break;
1932
1933                                         default:
1934                                         /* l3-data is sent to LCR */
1935                                         stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1936                                 }
1937                                 /* free message */
1938                                 free_l3_msg(l3m);
1939                         }
1940                 }
1941                 mISDNport = mISDNport->next;
1942         }
1943         return 0;
1944 }
1945
1946 /* l2 establish timer fires */
1947 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1948 {
1949         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1950
1951         if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1952 //              PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1953                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1954                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1955         }
1956
1957         return 0;
1958 }
1959
1960 /* handle frames from bchannel */
1961 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1962 {
1963         struct mISDNport *mISDNport = (struct mISDNport *)instance;
1964         unsigned char buffer[2048+MISDN_HEADER_LEN];
1965         struct mISDNhead *hh = (struct mISDNhead *)buffer;
1966         int ret;
1967
1968         ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1969         if (ret < 0) {
1970                 PERROR("read error frame, errno %d\n", errno);
1971                 return 0;
1972         }
1973         if (ret < (int)MISDN_HEADER_LEN) {
1974                 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1975                 return 0;
1976         }
1977         switch(hh->prim) {
1978                 /* we don't care about confirms, we use rx data to sync tx */
1979                 case PH_DATA_CNF:
1980                 break;
1981
1982                 /* we receive audio data, we respond to it AND we send tones */
1983                 case PH_DATA_IND:
1984                 case DL_DATA_IND:
1985                 case PH_DATA_REQ:
1986                 case DL_DATA_REQ:
1987                 case PH_CONTROL_IND:
1988                 if (mISDNport->b_port[i])
1989                         mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1990                 else
1991                         PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1992                 break;
1993
1994                 case PH_ACTIVATE_IND:
1995                 case DL_ESTABLISH_IND:
1996                 case PH_ACTIVATE_CNF:
1997                 case DL_ESTABLISH_CNF:
1998                 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1999                 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2000                 break;
2001
2002                 case PH_DEACTIVATE_IND:
2003                 case DL_RELEASE_IND:
2004                 case PH_DEACTIVATE_CNF:
2005                 case DL_RELEASE_CNF:
2006                 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2007                 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2008                 break;
2009
2010                 default:
2011                 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2012         }
2013
2014         return 0;
2015 }
2016
2017 /* process timer events for bchannel handling */
2018 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2019 {
2020         struct mISDNport *mISDNport = (struct mISDNport *)instance;
2021 puts("fires");
2022
2023         bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2024
2025         return 0;
2026 }
2027
2028
2029 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2030 {
2031         /* IMPORTAINT:
2032          *
2033          * l3m must be queued, except for MT_ASSIGN
2034          *
2035          */
2036         struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2037         struct mbuffer *mb;
2038
2039         /* special MT_ASSIGN handling:
2040          *
2041          * if we request a PID from mlayer, we always do it while lcr is locked.
2042          * therefore we must check the MT_ASSIGN reply first before we lock.
2043          * this is because the MT_ASSIGN reply is received with the requesting
2044          * process, not by the mlayer thread!
2045          * this means, that the reply is sent during call of the request.
2046          * we must check if we get a reply and we know that we lcr is currently
2047          * locked.
2048          */
2049         if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2050                 /* let's do some checking if someone changes stack behaviour */
2051                 if (mt_assign_pid != 0)
2052                         FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2053                 mt_assign_pid = pid;
2054                 return(0);
2055         }
2056         /* queue message, create, if required */
2057         if (!l3m) {
2058                 l3m = alloc_l3_msg();
2059                 if (!l3m)
2060                         FATAL("No memory for layer 3 message\n");
2061         }
2062         mb = container_of(l3m, struct mbuffer, l3);
2063         l3m->type = cmd;
2064         l3m->pid = pid;
2065         mqueue_tail(&mISDNport->upqueue, mb);
2066         if (!upqueue_avail) {
2067                 // multiple threads may cause multiple calls of this section, but this
2068                 // results only in multiple processing of the upqueue read.
2069                 // this is no problem.
2070                 upqueue_avail = 1;
2071                 char byte = 0;
2072                 int ret;
2073                 ret = write(upqueue_pipe[1], &byte, 1);
2074         }
2075         return 0;
2076 }
2077
2078 int mISDN_getportbyname(int sock, int cnt, char *portname)
2079 {
2080         struct mISDN_devinfo devinfo;
2081         int port = 0, ret;
2082
2083         /* resolve name */
2084         while (port < cnt) {
2085                 devinfo.id = port;
2086                 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2087                 if (ret < 0)
2088                         return ret;
2089                 if (!strcasecmp(devinfo.name, portname))
2090                         break;
2091                 port++;
2092         }
2093         if (port == cnt)
2094                 return -EIO;
2095
2096         return (port);
2097 }
2098
2099 /*
2100  * global function to add a new card (port)
2101  */
2102 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2103 {
2104         int ret;
2105         struct mISDNport *mISDNport, **mISDNportp;
2106         int port = ifport->portnum;
2107         int ptp = ifport->ptp;
2108         int force_nt = ifport->nt;
2109         int l1hold = ifport->l1hold;
2110         int l2hold = ifport->l2hold;
2111         int loop = 0;
2112         int ss5 = ifport->ss5;
2113         int i, cnt;
2114         int pri, bri, pots;
2115         int nt, te;
2116 //      struct mlayer3 *ml3;
2117         struct mISDN_devinfo devinfo;
2118         unsigned int protocol, prop;
2119
2120 #if defined WITH_GSM_BS && defined WITH_GSM_MS
2121         loop = ifport->gsm_ms | ifport->gsm_bs;
2122 #else
2123 #ifdef WITH_GSM_BS
2124         loop = ifport->gsm_bs;
2125 #endif
2126 #ifdef WITH_GSM_MS
2127         loop = ifport->gsm_ms;
2128 #endif
2129 #endif
2130 //printf("%s == %s\n", ifport->portname, options.loopback_int);
2131         if (!strcmp(ifport->portname, options.loopback_lcr))
2132                 loop = 1;
2133
2134         if (loop) {
2135                 if (mISDNloop_open())
2136                         return NULL;
2137         }
2138
2139         /* check port counts */
2140         ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2141         if (ret < 0) {
2142                 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2143                 return(NULL);
2144         }
2145
2146         if (cnt <= 0) {
2147                 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2148                 return(NULL);
2149         }
2150         if (port < 0) {
2151                 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2152                 if (port < 0) {
2153                         if (loop)
2154                                 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
2155                         else
2156                                 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2157                         return(NULL);
2158                 }
2159                 // note: 'port' has still the port number
2160         }
2161         if (port>cnt || port<0) {
2162                 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2163                 return(NULL);
2164         }
2165
2166         /* get port attributes */
2167         pri = bri = pots = nt = te = 0;
2168         devinfo.id = port;
2169         ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2170         if (ret < 0) {
2171                 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2172                 return(NULL);
2173         }
2174         if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2175                 bri = 1;
2176                 te = 1;
2177         }
2178         if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2179                 bri = 1;
2180                 nt = 1;
2181         }
2182         if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2183                 pri = 1;
2184                 te = 1;
2185         }
2186         if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2187                 pri = 1;
2188                 nt = 1;
2189         }
2190 #ifdef ISDN_P_FXS
2191         if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2192                 pots = 1;
2193                 te = 1;
2194         }
2195 #endif
2196 #ifdef ISDN_P_FXO
2197         if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2198                 pots = 1;
2199                 nt = 1;
2200         }
2201 #endif
2202         if (force_nt && !nt) {
2203                 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2204                 return(NULL);
2205         }
2206         if (bri && pri) {
2207                 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2208                 return(NULL);
2209         }
2210         if (pots && !bri && !pri) {
2211                 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2212                 return(NULL);
2213         }
2214         if (!bri && !pri) {
2215                 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2216                 return(NULL);
2217         }
2218         if (!nt && !te) {
2219                 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2220                 return(NULL);
2221         }
2222         /* set NT by turning off TE */
2223         if (force_nt && nt)
2224                 te = 0;
2225         /* if TE an NT is supported (and not forced to NT), turn off NT */
2226         if (te && nt)
2227                 nt = 0;
2228
2229         /* check for double use of port */
2230         if (nt) {
2231                 mISDNport = mISDNport_first;
2232                 while(mISDNport) {
2233                         if (mISDNport->portnum == port)
2234                                 break;
2235                         mISDNport = mISDNport->next;
2236                 }
2237                 if (mISDNport) {
2238                         PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2239                         return(NULL);
2240                 }
2241         }
2242
2243         /* check for continous channelmap with no bchannel on slot 16 */
2244         if (test_channelmap(0, devinfo.channelmap)) {
2245                 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2246                 return(NULL);
2247         }
2248         i = 1;
2249         while(i < (int)devinfo.nrbchan + 1) {
2250                 if (i == 16) {
2251                         if (test_channelmap(i, devinfo.channelmap)) {
2252                                 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2253                                 return(NULL);
2254                         }
2255                 } else {
2256                         if (!test_channelmap(i, devinfo.channelmap)) {
2257                                 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2258                                 return(NULL);
2259                         }
2260                 }
2261                 i++;
2262         }
2263
2264         /* add mISDNport structure */
2265         mISDNportp = &mISDNport_first;
2266         while(*mISDNportp)
2267                 mISDNportp = &((*mISDNportp)->next);
2268         mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2269         add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2270         if (loop | ss5) {
2271                 /* loop/ss5 link is always active */
2272                 mISDNport->l1link = 1;
2273                 mISDNport->l2link = 1;
2274         } else {
2275                 mISDNport->l1link = -1;
2276                 mISDNport->l2link = -1;
2277         }
2278 #ifdef WITH_GSM_BS
2279         mISDNport->gsm_bs = ifport->gsm_bs;
2280 #endif
2281 #ifdef WITH_GSM_MS
2282         mISDNport->gsm_ms = ifport->gsm_ms;
2283 #endif
2284         mISDNport->isloopback = loop;
2285         pmemuse++;
2286         *mISDNportp = mISDNport;
2287
2288         /* if pri, must set PTP */
2289         if (pri)
2290                 ptp = 1;
2291
2292         /* set ss5 params */
2293         if (ss5) {
2294                 /* try to keep interface enabled */
2295                 l1hold = 1;
2296                 l2hold = 1;
2297         }
2298         /* set l2hold */
2299         switch (l2hold) {
2300                 case -1: // off
2301                 l2hold = 0;
2302                 break;
2303                 case 1: // on
2304                 l2hold = 1;
2305                 break;
2306                 default:
2307                 if (ptp)
2308                         l2hold = 1;
2309                 else
2310                         l2hold = 0;
2311                 break;
2312         }
2313                 
2314         /* allocate ressources of port */
2315         protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2316         prop = (1 << MISDN_FLG_L2_CLEAN);
2317         if (ptp) // ptp forced
2318                prop |= (1 << MISDN_FLG_PTP);
2319         if (nt) // supports hold/retrieve on nt-mode
2320                prop |= (1 << MISDN_FLG_NET_HOLD);
2321         if (l1hold) // supports layer 1 hold
2322                prop |= (1 << MISDN_FLG_L1_HOLD);
2323         if (l2hold) // supports layer 2 hold
2324                prop |= (1 << MISDN_FLG_L2_HOLD);
2325         /* open layer 3 and init upqueue */
2326         if (loop) {
2327                 unsigned long on = 1;
2328                 struct sockaddr_mISDN addr;
2329
2330                 if (devinfo.nrbchan < 8) {
2331                         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);
2332 //                      mISDNport_close(mISDNport);
2333 //                      return(NULL);
2334                 }
2335
2336                 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
2337                         PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
2338                         mISDNport_close(mISDNport);
2339                         return(NULL);
2340                 }
2341                 /* set nonblocking io */
2342                 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2343                         PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
2344                         mISDNport_close(mISDNport);
2345                         return(NULL);
2346                 }
2347                 /* bind socket to dchannel */
2348                 memset(&addr, 0, sizeof(addr));
2349                 addr.family = AF_ISDN;
2350                 addr.dev = port;
2351                 addr.channel = 0;
2352                 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2353                         PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
2354                         mISDNport_close(mISDNport);
2355                         return(NULL);
2356                 }
2357         } else {
2358                 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2359                 mqueue_init(&mISDNport->upqueue);
2360                 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2361                 if (!mISDNport->ml3) {
2362                         mqueue_purge(&mISDNport->upqueue);
2363                         PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2364                         start_trace(port,
2365                                 ifport->interface,
2366                                 NULL,
2367                                 NULL,
2368                                 DIRECTION_NONE,
2369                                 CATEGORY_CH,
2370                                 0,
2371                                 "PORT (open failed)");
2372                         end_trace();
2373                         mISDNport_close(mISDNport);
2374                         return(NULL);
2375                 }
2376         }
2377
2378         SCPY(mISDNport->name, devinfo.name);
2379         mISDNport->b_num = devinfo.nrbchan;
2380         mISDNport->portnum = port;
2381         mISDNport->ntmode = nt;
2382         mISDNport->tespecial = ifport->tespecial;
2383         mISDNport->pri = pri;
2384         mISDNport->ptp = ptp;
2385         mISDNport->l1hold = l1hold;
2386         mISDNport->l2hold = l2hold;
2387         mISDNport->ss5 = ss5;
2388         PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2389         i = 0;
2390         while(i < mISDNport->b_num) {
2391                 mISDNport->b_state[i] = B_STATE_IDLE;
2392                 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2393                 i++;
2394         }
2395
2396         /* if ptp, pull up the link */
2397         if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2398                 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2399                 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2400                 add_trace("tei", NULL, "%d", 0);
2401                 end_trace();
2402                 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2403         }
2404
2405         /* for nt-mode ptmp the link is always up */
2406         if (mISDNport->ntmode && !mISDNport->ptp)
2407                 mISDNport->l2link = 1;
2408
2409         PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2410
2411         start_trace(mISDNport->portnum,
2412                     ifport->interface,
2413                     NULL,
2414                     NULL,
2415                     DIRECTION_NONE,
2416                     CATEGORY_CH,
2417                     0,
2418                     "PORT (open)");
2419         add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2420         add_trace("channels", NULL, "%d", mISDNport->b_num);
2421         if (mISDNport->ss5)
2422                 add_trace("ccitt#5", NULL, "enabled");
2423         end_trace();
2424
2425         return(mISDNport);
2426 }
2427
2428
2429 /*
2430  * load static port instances, if required by mISDNport
2431  */
2432 void mISDNport_static(struct mISDNport *mISDNport)
2433 {
2434         int i;
2435
2436         i = 0;
2437         while(i < mISDNport->b_num) {
2438 #ifdef WITH_SS5
2439                 if (mISDNport->ss5)
2440                         ss5_create_channel(mISDNport, i);
2441 #endif
2442                 i++;
2443         }
2444 }
2445
2446
2447 /*
2448  * function to free ALL cards (ports)
2449  */
2450 void mISDNport_close_all(void)
2451 {
2452         /* free all ports */
2453         while(mISDNport_first)
2454                 mISDNport_close(mISDNport_first);
2455 }
2456
2457 /*
2458  * free only one port
2459  */
2460 void mISDNport_close(struct mISDNport *mISDNport)
2461 {
2462         struct mISDNport **mISDNportp;
2463         class Port *port;
2464         class PmISDN *isdnport;
2465         int i;
2466
2467         /* remove all port instance that are linked to this mISDNport */
2468         again:
2469         port = port_first;
2470         while(port) {
2471                 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2472                         isdnport = (class PmISDN *)port;
2473                         if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2474                                 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2475                                 delete isdnport;
2476                                 goto again;
2477                         }
2478                 }
2479                 port = port->next;
2480         }
2481
2482         /* only if we are already part of interface */
2483         if (mISDNport->ifport) {
2484                 start_trace(mISDNport->portnum,
2485                             mISDNport->ifport->interface,
2486                             NULL,
2487                             NULL,
2488                             DIRECTION_NONE,
2489                             CATEGORY_CH,
2490                             0,
2491                             "PORT (close)");
2492                 end_trace();
2493         }
2494
2495         /* free bchannels */
2496         i = 0;
2497         while(i < mISDNport->b_num) {
2498                 if (mISDNport->b_sock[i].inuse) {
2499                         _bchannel_destroy(mISDNport, i);
2500                         PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2501                 }
2502                 if (mISDNport->b_timer[i].inuse) {
2503                         del_timer(&mISDNport->b_timer[i]);
2504                 }
2505                 i++;
2506         }
2507         del_timer(&mISDNport->l2establish);
2508
2509         /* close layer 3, if open */
2510         if (!mISDNport->isloopback && mISDNport->ml3) {
2511                 close_layer3(mISDNport->ml3);
2512         }
2513
2514         /* close gsm socket, if open */
2515         if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
2516                 close(mISDNport->lcr_sock);
2517         }
2518
2519         /* purge upqueue */
2520         if (!mISDNport->isloopback)
2521                 mqueue_purge(&mISDNport->upqueue);
2522
2523         /* remove from list */
2524         mISDNportp = &mISDNport_first;
2525         while(*mISDNportp) {
2526                 if (*mISDNportp == mISDNport) {
2527                         *mISDNportp = (*mISDNportp)->next;
2528                         mISDNportp = NULL;
2529                         break;
2530                 }
2531                 mISDNportp = &((*mISDNportp)->next);
2532         }
2533
2534         if (mISDNportp)
2535                 FATAL("mISDNport not in list\n");
2536         
2537         FREE(mISDNport, sizeof(struct mISDNport));
2538         pmemuse--;
2539
2540 }
2541
2542
2543 /*
2544  * enque data from upper buffer
2545  */
2546 void PmISDN::txfromup(unsigned char *data, int length)
2547 {
2548         unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2549         struct mISDNhead *hh = (struct mISDNhead *)buf;
2550         int ret;
2551
2552         if (p_m_b_index < 0)
2553                 return;
2554         if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2555                 return;
2556
2557         /* check if high priority tones exist
2558          * ignore data in this case
2559          */
2560         if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2561                 return;
2562
2563         /* preload procedure
2564          * if transmit buffer in DSP module is empty,
2565          * preload it to DSP_LOAD to prevent jitter gaps.
2566          */
2567         if (p_m_load == 0 && ISDN_LOAD > 0) {
2568                 hh->prim = PH_DATA_REQ; 
2569                 hh->id = 0;
2570                 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2571                 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2572                 if (ret <= 0)
2573                         PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2574                 p_m_load += ISDN_LOAD;
2575                 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2576         }
2577
2578         /* drop if load would exceed ISDN_MAXLOAD
2579          * this keeps the delay not too high
2580          */
2581         if (p_m_load+length > ISDN_MAXLOAD)
2582                 return;
2583
2584         /* make and send frame */
2585         hh->prim = PH_DATA_REQ;
2586         hh->id = 0;
2587         memcpy(buf+MISDN_HEADER_LEN, data, length);
2588         ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2589         if (ret <= 0)
2590                 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2591         p_m_load += length;
2592 }
2593
2594 int PmISDN::inband_send(unsigned char *buffer, int len)
2595 {
2596         PERROR("this function must be derived to function!\n");
2597         return 0;
2598 }
2599
2600 void PmISDN::inband_send_on(void)
2601 {
2602         PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2603         p_m_inband_send_on = 1;
2604         /* trigger inband transmit */
2605         update_load();
2606 }
2607
2608 void PmISDN::inband_send_off(void)
2609 {
2610         PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2611         p_m_inband_send_on = 0;
2612 }
2613
2614 void PmISDN::inband_receive(unsigned char *buffer, int len)
2615 {
2616 //
2617 //      if (len >= SS5_DECODER_NPOINTS)
2618 //              ss5_decode(buffer, SS5_DECODER_NPOINTS);
2619         PERROR("this function must be derived to function!\n");
2620 }
2621
2622 void PmISDN::inband_receive_on(void)
2623 {
2624         /* this must work during constructor, see ss5.cpp */
2625         PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2626         p_m_inband_receive_on = 1;
2627         update_rxoff();
2628 }
2629
2630 void PmISDN::inband_receive_off(void)
2631 {
2632         PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2633         p_m_inband_receive_on = 0;
2634         update_rxoff();
2635 }
2636
2637 void PmISDN::mute_on(void)
2638 {
2639         if (p_m_mute)
2640                 return;
2641         PDEBUG(DEBUG_PORT, "turning mute on.\n");
2642         p_m_mute = 1;
2643         set_conf(p_m_conf, 0);
2644 }
2645
2646 void PmISDN::mute_off(void)
2647 {
2648         if (!p_m_mute)
2649                 return;
2650         PDEBUG(DEBUG_PORT, "turning mute off.\n");
2651         p_m_mute = 0;
2652         set_conf(0, p_m_conf);
2653 }
2654
2655