work on chan_lcr
[lcr.git] / bchannel.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN channel handlin for remote application                              **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12
13
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <string.h>
19 #include <poll.h>
20 #include <errno.h>
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #ifdef SOCKET_MISDN
26 #include <netinet/udp.h>
27 #include <netinet/in.h>
28 #include <netdb.h>
29 #include <sys/socket.h>
30 #include <pthread.h>
31 #else
32 #include "mISDNlib.h"
33 #include <linux/mISDNif.h>
34 #endif
35 #include "bchannel.h"
36
37 #ifndef ISDN_PID_L4_B_USER
38 #define ISDN_PID_L4_B_USER 0x440000ff
39 #endif
40
41 #define PERROR(arg...) fprintf(stderr, ##arg)
42 #define PDEBUG(arg...) while(0)
43
44 pid_t   bchannel_pid;
45
46 enum {
47         BSTATE_IDLE,
48         BSTATE_ACTIVATING,
49         BSTATE_ACTIVE,
50 };
51
52 #ifdef SOCKET_MISDN
53
54 int bchannel_initialize(void)
55 {
56         return(0);
57 }
58
59 void bchannel_deinitialize(void)
60 {
61 }
62 #else
63 int bchannel_entity = 0; /* used for udevice */
64 int bchannel_device = -1; /* the device handler and port list */
65
66 int bchannel_initialize(void)
67 {
68         char debug_log[128];
69         unsigned char buff[1025];
70         iframe_t *frm = (iframe_t *)buff;
71         int ret;
72
73         /* open mISDNdevice if not already open */
74         if (bchannel_device < 0)
75         {
76                 ret = mISDN_open();
77                 if (ret < 0)
78                 {
79                         PERROR("cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
80                         return(-1);
81                 }
82                 bchannel_device = ret;
83                 PDEBUG("mISDN device opened.\n");
84
85                 /* create entity for layer 3 TE-mode */
86                 mISDN_write_frame(bchannel_device, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
87                 ret = mISDN_read_frame(bchannel_device, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
88                 if (ret < (int)mISDN_HEADER_LEN)
89                 {
90                         noentity:
91                         PERROR("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
92                         return(-1);
93                 }
94                 bchannel_entity = frm->dinfo & 0xffff;
95                 if (!bchannel_entity)
96                         goto noentity;
97         }
98         return(0);
99 }
100
101 void bchannel_deinitialize(void)
102 {
103         unsigned char buff[1025];
104
105         if (bchannel_device >= 0)
106         {
107                 /* free entity */
108                 mISDN_write_frame(bchannel_device, buff, 0, MGR_DELENTITY | REQUEST, bchannel_entity, 0, NULL, TIMEOUT_1SEC);
109                 /* close device */
110                 mISDN_close(bchannel_device);
111                 bchannel_device = -1;
112         }
113 }
114 #endif
115
116 /*
117  * send control information to the channel (dsp-module)
118  */
119 static void ph_control(unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
120 {
121 #ifdef SOCKET_MISDN
122         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
123         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
124         unsigned long *d = buffer+MISDN_HEADER_LEN;
125         int ret;
126
127         ctrl->prim = PH_CONTROL_REQ;
128         ctrl->id = 0;
129         *d++ = c1;
130         *d++ = c2;
131         ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
132         if (!ret)
133                 PERROR("Failed to send to socket %d\n", handle);
134 #else
135         unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
136         iframe_t *ctrl = (iframe_t *)buffer; 
137         unsigned long *d = (unsigned long *)&ctrl->data.p;
138
139         ctrl->prim = PH_CONTROL | REQUEST;
140         ctrl->addr = handle | FLG_MSG_DOWN;
141         ctrl->dinfo = 0;
142         ctrl->len = sizeof(int)*2;
143         *d++ = c1;
144         *d++ = c2;
145         mISDN_write(bchannel_device, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
146 #endif
147 #if 0
148         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
149         if (c1 == CMX_CONF_JOIN)
150                 add_trace(trace_name, NULL, "0x%08x", trace_value);
151         else
152                 add_trace(trace_name, NULL, "%d", trace_value);
153         end_trace();
154 #endif
155 }
156
157 static void ph_control_block(unsigned long handle, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
158 {
159 #ifdef SOCKET_MISDN
160         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
161         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
162         unsigned long *d = buffer+MISDN_HEADER_LEN;
163         int ret;
164
165         ctrl->prim = PH_CONTROL_REQ;
166         ctrl->id = 0;
167         *d++ = c1;
168         memcpy(d, c2, c2_len);
169         ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
170         if (!ret)
171                 PERROR("Failed to send to socket %d\n", handle);
172 #else
173         unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
174         iframe_t *ctrl = (iframe_t *)buffer;
175         unsigned long *d = (unsigned long *)&ctrl->data.p;
176
177         ctrl->prim = PH_CONTROL | REQUEST;
178         ctrl->addr = handle | FLG_MSG_DOWN;
179         ctrl->dinfo = 0;
180         ctrl->len = sizeof(int)+c2_len;
181         *d++ = c1;
182         memcpy(d, c2, c2_len);
183         mISDN_write(bchannel_device, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
184 #endif
185 #if 0
186         chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
187         add_trace(trace_name, NULL, "%d", trace_value);
188         end_trace();
189 #endif
190 }
191
192
193 /*
194  * create stack
195  */
196 int bchannel_create(struct bchannel *channel)
197 {
198         unsigned char buff[1024];
199         int ret;
200 #ifdef SOCKET_MISDN
201         unsigned long on = 1;
202         struct sockadd_mISDN addr;
203
204         if (channel->b_sock)
205         {
206                 PERROR("Error: Socket already created for handle 0x%x\n", channel->handle);
207                 return(0);
208         }
209
210         /* open socket */
211         channel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
212         if (channel->b_sock < 0)
213         {
214                 PERROR("Error: Failed to open bchannel-socket for handle 0x%x with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", channel->handle);
215                 return(0);
216         }
217         
218         /* set nonblocking io */
219         ret = ioctl(channel->b_sock, FIONBIO, &on);
220         if (ret < 0)
221         {
222                 PERROR("Error: Failed to set bchannel-socket handle 0x%x into nonblocking IO\n", channel->handle);
223                 close(channel->b_sock);
224                 channel->b_sock = -1;
225                 return(0);
226         }
227
228         /* bind socket to bchannel */
229         addr.family = AF_ISDN;
230         addr.dev = (channel->handle>>8)-1;
231         addr.channel = channel->handle && 0xff;
232         ret = bind(channel->b_sock, (struct sockaddr *)&addr, sizeof(addr));
233         if (ret < 0)
234         {
235                 PERROR("Error: Failed to bind bchannel-socket for handle 0x%x with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", channel->handle);
236                 close(channel->b_sock);
237                 channel->b_sock = -1;
238                 return(0);
239         }
240
241 #if 0
242         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
243         add_trace("channel", NULL, "%d", i+1+(i>=15));
244         add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
245         end_trace();
246 #endif
247 #else
248         layer_info_t li;
249         mISDN_pid_t pid;
250
251         if (channel->b_stid)
252         {
253                 PERROR("Error: stack already created for address 0x%x\n", channel->b_stid);
254                 return(0);
255         }
256
257         if (channel->b_addr)
258         {
259                 PERROR("Error: stack already created for address 0x%x\n", channel->b_addr);
260                 return(0);
261         }
262
263         /* create new layer */
264         PDEBUG("creating new layer for stid 0x%x.\n" , channel->handle);
265         memset(&li, 0, sizeof(li));
266         memset(&pid, 0, sizeof(pid));
267         li.object_id = -1;
268         li.extentions = 0;
269         li.st = channel->handle;
270         strcpy(li.name, "B L4");
271         li.pid.layermask = ISDN_LAYER((4));
272         li.pid.protocol[4] = ISDN_PID_L4_B_USER;
273         ret = mISDN_new_layer(bchannel_device, &li);
274         if (ret)
275         {
276                 failed_new_layer:
277                 PERROR("mISDN_new_layer() failed to add bchannel for stid 0x%x.\n", channel->handle);
278                 goto failed;
279         }
280         if (!li.id)
281         {
282                 goto failed_new_layer;
283         }
284         channel->b_stid = channel->handle;
285         channel->b_addr = li.id;
286         PDEBUG("new layer (b_addr=0x%x)\n", channel->b_addr);
287
288         /* create new stack */
289         pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
290         pid.protocol[2] = ISDN_PID_L2_B_TRANS;
291         pid.protocol[3] = ISDN_PID_L3_B_DSP;
292         pid.protocol[4] = ISDN_PID_L4_B_USER;
293         pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
294         ret = mISDN_set_stack(bchannel_device, channel->b_stid, &pid);
295         if (ret)
296         {
297                 stack_error:
298                 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel stid=0x%x\n", ret, channel->b_stid);
299                 mISDN_write_frame(bchannel_device, buff, channel->b_addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
300                 goto failed;
301         }
302         ret = mISDN_get_setstack_ind(bchannel_device, channel->b_addr);
303         if (ret)
304                 goto stack_error;
305
306         /* get layer id */
307         channel->b_addr = mISDN_get_layerid(bchannel_device, channel->b_stid, 4);
308         if (!channel->b_addr)
309                 goto stack_error;
310 #if 0
311         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
312         add_trace("channel", NULL, "%d", i+1+(i>=15));
313         add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
314         add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
315         end_trace();
316 #endif
317 #endif
318
319         return(1);
320
321 failed:
322         channel->b_stid = 0;
323         channel->b_addr = 0;
324         return(0);
325 }
326
327
328 /*
329  * activate / deactivate request
330  */
331 void bchannel_activate(struct bchannel *channel, int activate)
332 {
333 #ifdef SOCKET_MISDN
334         struct mISDNhead act;
335         int ret;
336
337         act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ; 
338         act.id = 0;
339         ret = sendto(channel->b_sock, &act, MISDN_HEADER_LEN, 0, NULL, 0);
340         if (!ret)
341                 PERROR("Failed to send to socket %d\n", channel->b_sock);
342 #else
343         iframe_t act;
344
345         /* activate bchannel */
346         act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST; 
347         act.addr = channel->b_addr | FLG_MSG_DOWN;
348         act.dinfo = 0;
349         act.len = 0;
350         mISDN_write(bchannel_device, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
351 #endif
352
353         channel->b_state = BSTATE_ACTIVATING;
354 #if 0
355         /* trace */
356         chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
357         add_trace("channel", NULL, "%d", i+1+(i>=15));
358         end_trace();
359 #endif
360 }
361
362
363 /*
364  * set features
365  */
366 static void bchannel_activated(struct bchannel *channel)
367 {
368 #ifdef SOCKET_MISDN
369         int handle;
370
371         handle = channel->b_sock;
372 #else
373         unsigned long handle;
374
375         handle = channel->b_addr;
376 #endif
377
378         /* set dsp features */
379         if (channel->b_txdata)
380                 ph_control(handle, (channel->b_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", channel->b_txdata);
381         if (channel->b_delay)
382                 ph_control(handle, CMX_DELAY, channel->b_delay, "DSP-DELAY", channel->b_delay);
383         if (channel->b_tx_dejitter)
384                 ph_control(handle, (channel->b_tx_dejitter)?CMX_TX_DEJITTER:CMX_TX_DEJ_OFF, 0, "DSP-DELAY", channel->b_tx_dejitter);
385         if (channel->b_tx_gain)
386                 ph_control(handle, VOL_CHANGE_TX, channel->b_tx_gain, "DSP-TX_GAIN", channel->b_tx_gain);
387         if (channel->b_rx_gain)
388                 ph_control(handle, VOL_CHANGE_RX, channel->b_rx_gain, "DSP-RX_GAIN", channel->b_rx_gain);
389         if (channel->b_pipeline[0])
390                 ph_control_block(handle, PIPELINE_CFG, channel->b_pipeline, strlen(channel->b_pipeline)+1, "DSP-PIPELINE", 0);
391         if (channel->b_conf)
392                 ph_control(handle, CMX_CONF_JOIN, channel->b_conf, "DSP-CONF", channel->b_conf);
393         if (channel->b_echo)
394                 ph_control(handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
395         if (channel->b_tone)
396                 ph_control(handle, TONE_PATT_ON, channel->b_tone, "DSP-TONE", channel->b_tone);
397         if (channel->b_rxoff)
398                 ph_control(handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
399 //      if (channel->b_txmix)
400 //              ph_control(handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
401         if (channel->b_dtmf)
402                 ph_control(handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
403         if (channel->b_crypt_len)
404                 ph_control_block(handle, BF_ENABLE_KEY, channel->b_crypt_key, channel->b_crypt_len, "DSP-CRYPT", channel->b_crypt_len);
405         if (channel->b_conf)
406                 ph_control(handle, CMX_CONF_JOIN, channel->b_conf, "DSP-CONF", channel->b_conf);
407
408         channel->b_state = BSTATE_ACTIVE;
409 }
410
411 /*
412  * destroy stack
413  */
414 static void bchannel_destroy(struct bchannel *channel)
415 {
416 #ifdef SOCKET_MISDN
417 #if 0
418         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
419         add_trace("channel", NULL, "%d", i+1+(i>=15));
420         add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
421         end_trace();
422 #endif
423         if (channel->b_sock > -1)
424         {
425                 close(channel->b_sock);
426                 channel->b_sock = -1;
427         }
428 #else
429         unsigned char buff[1024];
430
431 #if 0
432         chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
433         add_trace("channel", NULL, "%d", i+1+(i>=15));
434         add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
435         add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
436         end_trace();
437 #endif
438         /* remove our stack only if set */
439         if (channel->b_addr)
440         {
441                 PDEBUG("free stack (b_addr=0x%x)\n", channel->b_addr);
442                 mISDN_clear_stack(bchannel_device, channel->b_stid);
443                 mISDN_write_frame(bchannel_device, buff, channel->b_addr | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
444                 channel->b_stid = 0;
445                 channel->b_addr = 0;
446         }
447 #endif
448         channel->b_state = BSTATE_IDLE;
449 }
450
451
452 /*
453  * whenever we get audio data from bchannel, we process it here
454  */
455 static void bchannel_receive(struct bchannel *channel, unsigned long prim, unsigned long dinfo, unsigned char *data, int len)
456 {
457         unsigned long cont = *((unsigned long *)data);
458         unsigned char *data_temp;
459         unsigned long length_temp;
460         unsigned char *p;
461         int l;
462
463         if (prim == (PH_CONTROL | INDICATION))
464         {
465                 if (len < 4)
466                 {
467                         PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
468                         return;
469                 }
470                 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
471                 {
472 #if 0
473                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
474                         add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
475                         end_trace();
476 #endif
477                         if (channel->rx_dtmf)
478                                 channel->rx_dtmf(channel, cont & DTMF_TONE_MASK);
479                         return;
480                 }
481                 switch(cont)
482                 {
483                         case BF_REJECT:
484 #if 0
485                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
486                         add_trace("DSP-CRYPT", NULL, "error");
487                         end_trace();
488 #endif
489                         break;
490
491                         case BF_ACCEPT:
492 #if 0
493                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
494                         add_trace("DSP-CRYPT", NULL, "ok");
495                         end_trace();
496 #endif
497                         break;
498
499                         default:
500 #if 0
501                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
502                         add_trace("unknown", NULL, "0x%x", cont);
503                         end_trace();
504 #else
505                         ;
506 #endif
507                 }
508                 return;
509         }
510         if (prim == (PH_SIGNAL | INDICATION))
511         {
512                 switch(dinfo)
513                 {
514                         case CMX_TX_DATA:
515                         if (!channel->b_txdata)
516                         {
517                                 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
518                                 PDEBUG("PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
519                                 return;
520                         }
521                         break;
522
523                         default:
524 #if 0
525                         chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
526                         add_trace("unknown", NULL, "0x%x", frm->dinfo);
527                         end_trace();
528 #else
529                         ;
530 #endif
531                 }
532                 return;
533         }
534         if (prim != PH_DATA_IND && prim != DL_DATA_IND)
535         {
536                 PERROR("Bchannel received unknown primitve: 0x%x\n", prim);
537                 return;
538         }
539         /* calls will not process any audio data unless
540          * the call is connected OR interface features audio during call setup.
541          */
542
543         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
544         if (channel->b_rxoff)
545         {
546                 PDEBUG("PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
547                 return;
548         }
549
550         if (channel->rx_data)
551                 channel->rx_data(channel, data, len);
552 }
553
554
555 /*
556  * transmit data to bchannel
557  */
558 void bchannel_transmit(struct bchannel *channel, unsigned char *data, int len)
559 {
560         unsigned char buff[1025];
561         iframe_t *frm = (iframe_t *)buff;
562
563         if (channel->b_state != BSTATE_ACTIVE)
564                 return;
565 #ifdef SOCKET_MISDN
566         frm->prim = DL_DATA_REQ;
567         frm->id = 0;
568         ret = sendto(channel->b_sock, data, len, 0, NULL, 0);
569         if (!ret)
570                 PERROR("Failed to send to socket %d\n", channel->b_sock);
571 #else
572         frm->prim = DL_DATA | REQUEST; 
573         frm->addr = channel->b_addr | FLG_MSG_DOWN;
574         frm->dinfo = 0;
575         frm->len = len;
576         if (frm->len)
577                 mISDN_write(bchannel_device, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
578 #endif
579 }
580
581
582 /*
583  * join bchannel
584  */
585 void bchannel_join(struct bchannel *channel, unsigned short id)
586 {
587 #ifdef SOCKET_MISDN
588         int handle;
589
590         handle = channel->b_sock;
591 #else
592         unsigned long handle;
593
594         handle = channel->b_addr;
595 #endif
596         if (id)
597                 channel->b_conf = (id<<16) + bchannel_pid;
598         else
599                 channel->b_conf = 0;
600         if (channel->b_state == BSTATE_ACTIVE)
601                 ph_control(handle, CMX_CONF_JOIN, channel->b_conf, "DSP-CONF", channel->b_conf);
602 }
603
604
605 /*
606  * main loop for processing messages from mISDN
607  */
608 #ifdef SOCKET_MISDN
609 int bchannel_handle(void)
610 {
611         int ret, work = 0;
612         struct bchannel *channel;
613         int i;
614         char buffer[2048+MISDN_HEADER_LEN];
615         struct mISDNhead *hh = (struct mISDNhead *)buffer;
616
617         /* process all bchannels */
618         channel = bchannel_first;
619         while(channel)
620         {
621                 /* handle message from bchannel */
622                 if (channel->b_sock > -1)
623                 {
624                         ret = recv(channel->b_sock, buffer, sizeof(buffer), 0);
625                         if (ret >= MISDN_HEADER_LEN)
626                         {
627                                 work = 1;
628                                 switch(hh->prim)
629                                 {
630                                         /* we don't care about confirms, we use rx data to sync tx */
631                                         case PH_DATA_CONF:
632                                         case DL_DATA_CONF:
633                                         break;
634
635                                         /* we receive audio data, we respond to it AND we send tones */
636                                         case PH_DATA_IND:
637                                         case DL_DATA_IND:
638                                         case PH_SIGNAL_IND:
639                                         case PH_CONTROL | INDICATION:
640                                         bchannel_receive(channel, hh->prim, hh->dinfo, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
641                                         break;
642
643                                         case PH_ACTIVATE_IND:
644                                         case DL_ESTABLISH_IND:
645                                         case PH_ACTIVATE_CONF:
646                                         case DL_ESTABLISH_CONF:
647                                         PDEBUG("DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", channel->b_sock);
648                                         bchannel_activated(channel);
649                                         break;
650
651                                         case PH_DEACTIVATE_IND:
652                                         case DL_RELEASE_IND:
653                                         case PH_DEACTIVATE_CONF:
654                                         case DL_RELEASE_CONF:
655                                         PDEBUG("DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", channel->b_sock);
656 //                                      bchannel_deactivated(channel);
657                                         break;
658
659                                         default:
660                                         PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, channel->b_sock, msg->len);
661                                 }
662                         } else
663                         {
664                                 if (ret < 0 && errno != EWOULDBLOCK)
665                                         PERROR("Read from socket %d failed with return code %d\n", channel->b_sock, ret);
666                         }
667                 }
668                 channel = channel->next;
669         }
670
671         /* if we received at least one b-frame, we will return 1 */
672         return(work);
673 }
674 #else
675 int bchannel_handle(void)
676 {
677         int i;
678         struct bchannel *channel;
679         iframe_t *frm;
680         unsigned char buffer[2048];
681         struct mISDNhead *hh = (struct mISDNhead *)buffer;
682         int len;
683
684         /* no device, no read */
685         if (bchannel_device < 0)
686                 return(0);
687
688         /* get message from kernel */
689         len = mISDN_read(bchannel_device, buffer, sizeof(buffer), 0);
690         if (len < 0)
691         {
692                 if (errno == EAGAIN)
693                         return(0);
694                 PERROR("Failed to do mISDN_read()\n");
695                 return(0);
696         }
697         if (!len)
698         {
699 //              printf("%s: ERROR: mISDN_read() returns nothing\n");
700                 return(0);
701         }
702         frm = (iframe_t *)buffer;
703
704         /* global prim */
705         switch(frm->prim)
706         {
707                 case MGR_DELLAYER | CONFIRM:
708                 case MGR_INITTIMER | CONFIRM:
709                 case MGR_ADDTIMER | CONFIRM:
710                 case MGR_DELTIMER | CONFIRM:
711                 case MGR_REMOVETIMER | CONFIRM:
712                 return(1);
713         }
714
715         /* find the mISDNport that belongs to the stack */
716         channel = bchannel_first;
717         while(channel)
718         {
719                 if (frm->addr == channel->b_addr)
720                         break;
721                 channel = channel->next;
722         } 
723         if (!channel)
724         {
725                 PERROR("message belongs to no channel: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, len);
726                 goto out;
727         }
728
729         /* b-message */
730         switch(frm->prim)
731         {
732                 /* we don't care about confirms, we use rx data to sync tx */
733                 case PH_DATA | CONFIRM:
734                 case DL_DATA | CONFIRM:
735                 break;
736
737                 /* we receive audio data, we respond to it AND we send tones */
738                 case PH_DATA | INDICATION:
739                 case DL_DATA | INDICATION:
740                 case PH_CONTROL | INDICATION:
741                 case PH_SIGNAL | INDICATION:
742                 bchannel_receive(channel, frm->prim, frm->dinfo, (unsigned char *)frm->data.p, frm->len);
743                 break;
744
745                 case PH_ACTIVATE | INDICATION:
746                 case DL_ESTABLISH | INDICATION:
747                 case PH_ACTIVATE | CONFIRM:
748                 case DL_ESTABLISH | CONFIRM:
749                 PDEBUG( "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
750                 bchannel_activated(channel);
751                 break;
752
753                 case PH_DEACTIVATE | INDICATION:
754                 case DL_RELEASE | INDICATION:
755                 case PH_DEACTIVATE | CONFIRM:
756                 case DL_RELEASE | CONFIRM:
757                 PDEBUG("DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
758 //              bchannel_deactivated(channel);
759                 break;
760
761                 default:
762                 PERROR("message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, len);
763         }
764
765         out:
766         return(1);
767 }
768 #endif
769
770
771 /*
772  * bchannel channel handling
773  */
774 struct bchannel *bchannel_first = NULL;
775 struct bchannel *find_bchannel_handle(unsigned long handle)
776 {
777         struct bchannel *channel = bchannel_first;
778
779         while(channel)
780         {
781                 if (channel->handle == handle)
782                         break;
783                 channel = channel->next;
784         }
785         return(channel);
786 }
787
788 struct bchannel *find_bchannel_ref(unsigned long ref)
789 {
790         struct bchannel *channel = bchannel_first;
791
792         while(channel)
793         {
794                 if (channel->ref == ref)
795                         break;
796                 channel = channel->next;
797         }
798         return(channel);
799 }
800
801 struct bchannel *alloc_bchannel(unsigned long handle)
802 {
803         struct bchannel **channelp = &bchannel_first;
804
805         while(*channelp)
806                 channelp = &((*channelp)->next);
807
808         *channelp = (struct bchannel *)malloc(sizeof(struct bchannel));
809         if (!*channelp)
810                 return(NULL);
811         (*channelp)->handle = handle;
812         (*channelp)->b_state = BSTATE_IDLE;
813                 
814         return(*channelp);
815 }
816
817 void free_bchannel(struct bchannel *channel)
818 {
819         struct bchannel **temp = &bchannel_first;
820
821         while(*temp)
822         {
823                 if (*temp == channel)
824                 {
825                         *temp = (*temp)->next;
826 #ifdef SOCKET_MISDN
827                         if (channel->b_sock > -1)
828 #else
829                         if (channel->b_stid)
830 #endif
831                         bchannel_destroy(channel);
832                         if (channel->call)
833                         {
834                                 if (channel->call->channel)
835                                         channel->call->channel = NULL;
836                         }
837                         if (channel->bridge_channel)
838                         {
839                                 if (channel->bridge_channel->bridge_channel)
840                                         channel->bridge_channel->bridge_channel = NULL;
841                         }
842                         free(channel);
843                         return;
844                 }
845                 temp = &((*temp)->next);
846         }
847 }
848
849