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