- Fixed HLC (higher layer capability) modification to LCR routing.
[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 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <poll.h>
17 #include <errno.h>
18 #include <sys/ioctl.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <netinet/udp.h>
23 #include <netinet/in.h>
24 #include <netdb.h>
25 #include <sys/socket.h>
26 #include <mISDNif.h>
27
28 #define AF_COMPATIBILITY_FUNC 1
29 #define MISDN_OLD_AF_COMPATIBILITY 1
30 #include <compat_af_isdn.h>
31
32 #define HAVE_ATTRIBUTE_always_inline 1
33 #define HAVE_ARPA_INET_H 1
34 #define HAVE_TIMERSUB 1
35
36 #include <asterisk/compiler.h>
37 #include <asterisk/frame.h>
38
39 /* Choose if you want to have chan_lcr for Asterisk 1.4.x or CallWeaver 1.2.x */
40 /* #define LCR_FOR_CALLWEAVER */
41
42 #ifdef LCR_FOR_CALLWEAVER
43 #include <asterisk/phone_no_utils.h>
44 #include <asterisk/logger.h>
45 #include <asterisk/module.h>
46 #include <asterisk/channel.h>
47 #endif
48
49 #include "extension.h"
50 #include "message.h"
51 #include "lcrsocket.h"
52 #include "cause.h"
53 #include "select.h"
54 #include "bchannel.h"
55 #include "chan_lcr.h"
56 #include "callerid.h"
57 #include "options.h"
58
59
60 #ifndef ISDN_PID_L4_B_USER
61 #define ISDN_PID_L4_B_USER 0x440000ff
62 #endif
63
64 pid_t   bchannel_pid;
65
66 enum {
67         BSTATE_IDLE,
68         BSTATE_ACTIVATING,
69         BSTATE_ACTIVE,
70         BSTATE_DEACTIVATING,
71 };
72
73 static void bchannel_send_queue(struct bchannel *bchannel);
74
75 int bchannel_initialize(void)
76 {
77         init_af_isdn();
78
79         return 0;
80 }
81
82 void bchannel_deinitialize(void)
83 {
84 }
85
86 /*
87  * send control information to the channel (dsp-module)
88  */
89 static void ph_control(int sock, unsigned int c1, unsigned int c2, char *trace_name, int trace_value, int b_mode)
90 {
91         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
92         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
93         unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
94         int ret;
95
96         if (b_mode != 0 && b_mode != 2)
97                 return;
98
99         CDEBUG(NULL, NULL, "Sending PH_CONTROL %s %x,%x\n", trace_name, c1, c2);
100         ctrl->prim = PH_CONTROL_REQ;
101         ctrl->id = 0;
102         *d++ = c1;
103         *d++ = c2;
104         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
105         if (ret < 0)
106                 CERROR(NULL, NULL, "Failed to send to socket %d\n", sock);
107 }
108
109 static void ph_control_block(int sock, unsigned int c1, void *c2, int c2_len, char *trace_name, int trace_value, int b_mode)
110 {
111         unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
112         struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
113         unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
114         int ret;
115
116         if (b_mode != 0 && b_mode != 2)
117                 return;
118
119         CDEBUG(NULL, NULL, "Sending PH_CONTROL (block) %s %x\n", trace_name, c1);
120         ctrl->prim = PH_CONTROL_REQ;
121         ctrl->id = 0;
122         *d++ = c1;
123         memcpy(d, c2, c2_len);
124         ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
125         if (ret < 0)
126                 CERROR(NULL, NULL, "Failed to send to socket %d\n", sock);
127 }
128
129 static int bchannel_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index);
130
131 /*
132  * create stack
133  */
134 int bchannel_create(struct bchannel *bchannel, int mode, int queue)
135 {
136         int ret;
137         struct sockaddr_mISDN addr;
138
139         if (bchannel->b_sock > -1) {
140                 CERROR(bchannel->call, NULL, "Socket already created for handle 0x%x\n", bchannel->handle);
141                 return 0;
142         }
143
144         /* open socket */
145         bchannel->b_mode = (mode & 3);
146         switch(bchannel->b_mode) {
147                 case 0:
148                 CDEBUG(bchannel->call, NULL, "Open DSP audio\n");
149                 bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
150                 break;
151                 case 1:
152                 CDEBUG(bchannel->call, NULL, "Open audio\n");
153                 bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW);
154                 break;
155                 case 2:
156                 CDEBUG(bchannel->call, NULL, "Open DSP HDLC\n");
157                 bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSPHDLC);
158                 break;
159                 case 3:
160                 CDEBUG(bchannel->call, NULL, "Open HDLC\n");
161                 bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_HDLC);
162                 break;
163         }
164         if (bchannel->b_sock < 0) {
165                 CERROR(bchannel->call, NULL, "Failed to open bchannel-socket for handle 0x%x with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", bchannel->handle);
166                 return 0;
167         }
168
169         /* register fd */
170         memset(&bchannel->lcr_fd, 0, sizeof(bchannel->lcr_fd));
171         bchannel->lcr_fd.fd = bchannel->b_sock;
172         register_fd(&bchannel->lcr_fd, LCR_FD_READ | LCR_FD_EXCEPT, bchannel_handle, bchannel, 0);
173
174         /* bind socket to bchannel */
175         addr.family = AF_ISDN;
176         addr.dev = (bchannel->handle>>8);
177         addr.channel = bchannel->handle & 0xff;
178         ret = bind(bchannel->b_sock, (struct sockaddr *)&addr, sizeof(addr));
179         if (ret < 0) {
180                 CERROR(bchannel->call, NULL, "Failed to bind bchannel-socket for handle 0x%x with mISDN-DSP layer. (port %d, channel %d) Did you load mISDN_dsp.ko?\n", bchannel->handle, addr.dev, addr.channel);
181                 unregister_fd(&bchannel->lcr_fd);
182                 close(bchannel->b_sock);
183                 bchannel->b_sock = -1;
184                 return 0;
185         }
186
187         /* queue */
188         if (bchannel->b_mode == 1 && queue) {
189                 bchannel->nodsp_queue_out = 0;
190                 bchannel->nodsp_queue_in = queue * 8;
191                 if (bchannel->nodsp_queue_in > QUEUE_BUFFER_MAX-1)
192                         bchannel->nodsp_queue_in = QUEUE_BUFFER_MAX-1;
193                 bchannel->nodsp_queue = bchannel->nodsp_queue_in; /* store initial load */
194                 memset(&bchannel->nodsp_queue_buffer, (options.law=='a')?0x2a:0xff, QUEUE_BUFFER_SIZE);
195                 bchannel->queue_sent = 0;
196         } else
197                 bchannel->nodsp_queue = 0;
198                                                                                  
199         return 1;
200 }
201
202
203 /*
204  * activate / deactivate request
205  */
206 void bchannel_activate(struct bchannel *bchannel, int activate)
207 {
208         struct mISDNhead act;
209         int ret;
210
211         /* activate bchannel */
212         CDEBUG(bchannel->call, NULL, "%sActivating B-channel.\n", activate?"":"De-");
213         switch(bchannel->b_mode) {
214                 case 0:
215                 case 2:
216                 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ; 
217                 break;
218                 case 1:
219                 case 3:
220                 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ; 
221                 break;
222         }
223         act.id = 0;
224         ret = sendto(bchannel->b_sock, &act, MISDN_HEADER_LEN, 0, NULL, 0);
225         if (ret < 0)
226                 CERROR(bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock);
227
228         bchannel->b_state = (activate)?BSTATE_ACTIVATING:BSTATE_DEACTIVATING;
229 }
230
231
232 /*
233  * set features
234  */
235 static void bchannel_activated(struct bchannel *bchannel)
236 {
237         int sock;
238
239         sock = bchannel->b_sock;
240
241         /* set dsp features */
242         if (bchannel->b_txdata)
243                 ph_control(sock, (bchannel->b_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", bchannel->b_txdata, bchannel->b_mode);
244         if (bchannel->b_delay && bchannel->b_mode == 0)
245                 ph_control(sock, DSP_DELAY, bchannel->b_delay, "DSP-DELAY", bchannel->b_delay, bchannel->b_mode);
246         if (bchannel->b_tx_dejitter && bchannel->b_mode == 0)
247                 ph_control(sock, (bchannel->b_tx_dejitter)?DSP_TX_DEJITTER:DSP_TX_DEJ_OFF, 0, "DSP-TX_DEJITTER", bchannel->b_tx_dejitter, bchannel->b_mode);
248         if (bchannel->b_tx_gain && bchannel->b_mode == 0)
249                 ph_control(sock, DSP_VOL_CHANGE_TX, bchannel->b_tx_gain, "DSP-TX_GAIN", bchannel->b_tx_gain, bchannel->b_mode);
250         if (bchannel->b_rx_gain && bchannel->b_mode == 0)
251                 ph_control(sock, DSP_VOL_CHANGE_RX, bchannel->b_rx_gain, "DSP-RX_GAIN", bchannel->b_rx_gain, bchannel->b_mode);
252         if (bchannel->b_pipeline[0] && bchannel->b_mode == 0)
253                 ph_control_block(sock, DSP_PIPELINE_CFG, bchannel->b_pipeline, strlen(bchannel->b_pipeline)+1, "DSP-PIPELINE", 0, bchannel->b_mode);
254         if (bchannel->b_conf)
255                 ph_control(sock, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf, bchannel->b_mode);
256         if (bchannel->b_echo)
257                 ph_control(sock, DSP_ECHO_ON, 0, "DSP-ECHO", 1, bchannel->b_mode);
258         if (bchannel->b_tone && bchannel->b_mode == 0)
259                 ph_control(sock, DSP_TONE_PATT_ON, bchannel->b_tone, "DSP-TONE", bchannel->b_tone, bchannel->b_mode);
260         if (bchannel->b_rxoff)
261                 ph_control(sock, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1, bchannel->b_mode);
262 //      if (bchannel->b_txmix && bchannel->b_mode == 0)
263 //              ph_control(sock, DSP_MIX_ON, 0, "DSP-MIX", 1, bchannel->b_mode);
264         if (bchannel->b_dtmf && bchannel->b_mode == 0)
265                 ph_control(sock, DTMF_TONE_START, 0, "DSP-DTMF", 1, bchannel->b_mode);
266         if (bchannel->b_bf_len && bchannel->b_mode == 0)
267                 ph_control_block(sock, DSP_BF_ENABLE_KEY, bchannel->b_bf_key, bchannel->b_bf_len, "DSP-CRYPT", bchannel->b_bf_len, bchannel->b_mode);
268         if (bchannel->b_conf)
269                 ph_control(sock, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf, bchannel->b_mode);
270
271         bchannel->b_state = BSTATE_ACTIVE;
272 }
273
274 /*
275  * destroy stack
276  */
277 void bchannel_destroy(struct bchannel *bchannel)
278 {
279         if (bchannel->b_sock > -1) {
280                 unregister_fd(&bchannel->lcr_fd);
281                 close(bchannel->b_sock);
282                 bchannel->b_sock = -1;
283         }
284         bchannel->b_state = BSTATE_IDLE;
285 }
286
287
288 /*
289  * whenever we get audio data from bchannel, we process it here
290  */
291 static void bchannel_receive(struct bchannel *bchannel, unsigned char *buffer, int len)
292 {
293         struct mISDNhead *hh = (struct mISDNhead *)buffer;
294         unsigned char *data = buffer + MISDN_HEADER_LEN;
295         unsigned int cont = *((unsigned int *)data);
296         unsigned char *d;
297         int i;
298         struct bchannel *remote_bchannel;
299         int ret;
300
301         if (hh->prim == PH_CONTROL_IND) {
302                 /* non dsp -> ignore ph_control */
303                 if (bchannel->b_mode == 1 || bchannel->b_mode == 3)
304                         return;
305                 if (len < 4) {
306                         CERROR(bchannel->call, NULL, "SHORT READ OF PH_CONTROL INDICATION\n");
307                         return;
308                 }
309                 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
310                         if (bchannel->call)
311                                 lcr_in_dtmf(bchannel->call, cont & DTMF_TONE_MASK);
312                         return;
313                 }
314                 switch(cont) {
315                         case DSP_BF_REJECT:
316                         CERROR(bchannel->call, NULL, "Blowfish crypt rejected.\n");
317                         break;
318
319                         case DSP_BF_ACCEPT:
320                         CDEBUG(bchannel->call, NULL, "Blowfish crypt enabled.\n");
321                         break;
322
323                         default:
324                         CDEBUG(bchannel->call, NULL, "Unhandled bchannel control 0x%x.\n", cont);
325                 }
326                 return;
327         }
328         if (hh->prim == PH_DATA_REQ) {
329                 if (!bchannel->b_txdata) {
330                         /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
331                         CDEBUG(bchannel->call, NULL, "ignoring tx data, because 'txdata' is turned off\n");
332                         return;
333                 }
334                 return;
335         }
336         if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
337                 CERROR(bchannel->call, NULL, "Bchannel received unknown primitve: 0x%lx\n", hh->prim);
338                 return;
339         }
340         /* if calls are bridged, but not via dsp (no b_conf), forward here */
341         if (!bchannel->b_conf
342          && bchannel->call
343          && bchannel->call->bridge_call
344          && bchannel->call->bridge_call->bchannel) {
345                 remote_bchannel = bchannel->call->bridge_call->bchannel;
346 #if 0
347                 int i = 0;
348                 char string[4096] = "";
349                 while(i < len) {
350                         sprintf(string+strlen(string), " %02x", data[i]);
351                         i++;
352                 }
353                 CDEBUG(remote_bchannel->call, NULL, "Forwarding packet%s\n", string);
354 #endif
355                 hh->prim = PH_DATA_REQ;
356                 hh->id = 0;
357                 ret = sendto(remote_bchannel->b_sock, buffer, MISDN_HEADER_LEN+len, 0, NULL, 0);
358                 if (ret < 0)
359                         CERROR(remote_bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock);
360                 return;
361         }
362         /* calls will not process any audio data unless
363          * the call is connected OR interface features audio during call setup.
364          */
365
366         /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
367         if (bchannel->b_rxoff) {
368                 CDEBUG(bchannel->call, NULL, "ignoring data, because rx is turned off\n");
369                 return;
370         }
371
372         if (!bchannel->call) {
373                 CDEBUG(bchannel->call, NULL, "ignoring data, because no call associated with bchannel\n");
374                 return;
375         }
376         if (!bchannel->call->audiopath) {
377                 /* return, because we have no audio from port */
378                 return;
379         }
380
381         if (bchannel->call->pipe[1] < 0) {
382                 /* nobody there */
383                 return;
384         }
385
386         /* if no hdlc */
387         if (bchannel->b_mode == 0 || bchannel->b_mode == 1) {
388                 d = data;
389                 for (i = 0; i < len; i++) {
390                         *d = flip_bits[*d];
391                         d++;
392                 }
393         }
394
395         
396         len = write(bchannel->call->pipe[1], data, len);
397         if (len < 0)
398                 goto errout;
399
400         return;
401  errout:
402         close(bchannel->call->pipe[1]);
403         bchannel->call->pipe[1] = -1;
404         CDEBUG(bchannel->call, NULL, "broken pipe on bchannel pipe\n");
405 }
406
407
408 /*
409  * transmit data to bchannel
410  */
411 void bchannel_transmit(struct bchannel *bchannel, unsigned char *data, int len)
412 {
413         unsigned char buff[1024 + MISDN_HEADER_LEN], *p = buff + MISDN_HEADER_LEN;
414         struct mISDNhead *frm = (struct mISDNhead *)buff;
415         int ret;
416         int i;
417         int space, in;
418
419         if (bchannel->b_state != BSTATE_ACTIVE)
420                 return;
421         if (len > 1024 || len < 1)
422                 return;
423         switch(bchannel->b_mode) {
424         case 0:
425                 for (i = 0; i < len; i++)
426                         *p++ = flip_bits[*data++];
427                 frm->prim = DL_DATA_REQ;
428                 break;
429         case 1:
430                 for (i = 0; i < len; i++)
431                         *p++ = flip_bits[*data++];
432                 frm->prim = PH_DATA_REQ;
433                 break;
434         case 2:
435                 memcpy(p, data, len);
436                 frm->prim = DL_DATA_REQ;
437                 break;
438         case 3:
439                 memcpy(p, data, len);
440                 frm->prim = PH_DATA_REQ;
441                 break;
442         }
443         frm->id = 0;
444 #ifdef SEAMLESS_TEST
445         unsigned char test_tone[8] = {0x2a, 0x24, 0xb4, 0x24, 0x2a, 0x25, 0xb5, 0x25};
446         p = buff + MISDN_HEADER_LEN;
447         for (i = 0; i < len; i++)
448                 *p++ = test_tone[(bchannel->test + i) & 7];
449         bchannel->test = (bchannel->test + len) & 7;
450 #endif
451         if (bchannel->nodsp_queue) {
452                 space = (bchannel->nodsp_queue_out - bchannel->nodsp_queue_in - 1) & (QUEUE_BUFFER_SIZE - 1);
453                 if (len > space) {
454                         CERROR(bchannel->call, NULL, "Queue buffer overflow, space is %d, len is %d.\n", space, len);
455                         return;
456                 }
457                 p = buff + MISDN_HEADER_LEN;
458                 in = bchannel->nodsp_queue_in;
459                 for (i = 0; i < len; i++) {
460                         bchannel->nodsp_queue_buffer[in] = *p++;
461                         in = (in + 1) & (QUEUE_BUFFER_SIZE - 1);
462                 }
463                 bchannel->nodsp_queue_in = in;
464                 if (bchannel->queue_sent == 0) /* if there is no pending data */
465                         bchannel_send_queue(bchannel);
466                 return;
467         }
468         ret = sendto(bchannel->b_sock, buff, MISDN_HEADER_LEN+len, 0, NULL, 0);
469         if (ret < 0)
470                 CERROR(bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock);
471 }
472
473
474 /*
475  * in case of a send queue, we send from that queue rather directly
476  */
477 static void bchannel_send_queue(struct bchannel *bchannel)
478 {
479         unsigned char buff[1024 + MISDN_HEADER_LEN], *p = buff + MISDN_HEADER_LEN;
480         struct mISDNhead *frm = (struct mISDNhead *)buff;
481         int ret;
482         int i;
483         int len, out;
484
485         len = (bchannel->nodsp_queue_in - bchannel->nodsp_queue_out) & (QUEUE_BUFFER_SIZE - 1);
486         if (len == 0)
487                 return; /* mISDN driver received all load */
488 #if 0
489         printf("%4d:(%s|%s)\n", bchannel->nodsp_queue_out,
490                 "----------------------------------------------------------------"+64-len/(8192/64),
491                 "                                                                "+len/(8192/64));
492 #endif
493         if (len > 1024)
494                 len = 1024;
495         frm->prim = PH_DATA_REQ;
496         frm->id = 0;
497         out = bchannel->nodsp_queue_out;
498         for (i = 0; i < len; i++) {
499                 *p++ = bchannel->nodsp_queue_buffer[out];
500                 out = (out + 1) & (QUEUE_BUFFER_SIZE - 1);
501         }
502         bchannel->nodsp_queue_out = out;
503         ret = sendto(bchannel->b_sock, buff, MISDN_HEADER_LEN+len, 0, NULL, 0);
504         if (ret < 0)
505                 CERROR(bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock);
506         else
507                 bchannel->queue_sent = 1;
508 }
509
510
511 /*
512  * join bchannel
513  */
514 void bchannel_join(struct bchannel *bchannel, unsigned short id)
515 {
516         int sock;
517
518         sock = bchannel->b_sock;
519         if (id) {
520                 bchannel->b_conf = (id<<16) + bchannel_pid;
521                 bchannel->b_rxoff = 1;
522         } else {
523                 bchannel->b_conf = 0;
524                 bchannel->b_rxoff = 0;
525         }
526         if (bchannel->b_state == BSTATE_ACTIVE) {
527                 ph_control(sock, DSP_RECEIVE_OFF, bchannel->b_rxoff, "DSP-RX_OFF", bchannel->b_conf, bchannel->b_mode);
528                 ph_control(sock, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf, bchannel->b_mode);
529         }
530 }
531
532
533 /*
534  * dtmf bchannel
535  */
536 void bchannel_dtmf(struct bchannel *bchannel, int on)
537 {
538         int sock;
539
540         sock = bchannel->b_sock;
541         bchannel->b_dtmf = on;
542         if (bchannel->b_state == BSTATE_ACTIVE && bchannel->b_mode == 0)
543                 ph_control(sock, on?DTMF_TONE_START:DTMF_TONE_STOP, 0, "DSP-DTMF", 1, bchannel->b_mode);
544 }
545
546
547 /*
548  * blowfish bchannel
549  */
550 void bchannel_blowfish(struct bchannel *bchannel, unsigned char *key, int len)
551 {
552         int sock;
553
554         sock = bchannel->b_sock;
555         memcpy(bchannel->b_bf_key, key, len);
556         bchannel->b_bf_len = len;
557         if (bchannel->b_state == BSTATE_ACTIVE)
558                 ph_control_block(sock, DSP_BF_ENABLE_KEY, bchannel->b_bf_key, bchannel->b_bf_len, "DSP-CRYPT", bchannel->b_bf_len, bchannel->b_mode);
559 }
560
561
562 /*
563  * pipeline bchannel
564  */
565 void bchannel_pipeline(struct bchannel *bchannel, char *pipeline)
566 {
567         int sock;
568
569         sock = bchannel->b_sock;
570         strncpy(bchannel->b_pipeline, pipeline, sizeof(bchannel->b_pipeline)-1);
571         if (bchannel->b_state == BSTATE_ACTIVE)
572                 ph_control_block(sock, DSP_PIPELINE_CFG, bchannel->b_pipeline, strlen(bchannel->b_pipeline)+1, "DSP-PIPELINE", 0, bchannel->b_mode);
573 }
574
575
576 /*
577  * gain bchannel
578  */
579 void bchannel_gain(struct bchannel *bchannel, int gain, int tx)
580 {
581         int sock;
582
583         sock = bchannel->b_sock;
584         if (tx)
585                 bchannel->b_tx_gain = gain;
586         else
587                 bchannel->b_rx_gain = gain;
588         if (bchannel->b_state == BSTATE_ACTIVE && bchannel->b_mode == 0)
589                 ph_control(sock, (tx)?DSP_VOL_CHANGE_TX:DSP_VOL_CHANGE_RX, gain, (tx)?"DSP-TX_GAIN":"DSP-RX_GAIN", gain, bchannel->b_mode);
590 }
591
592
593 /*
594  * main loop for processing messages from mISDN
595  */
596 static int bchannel_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index)
597 {
598         struct bchannel *bchannel = (struct bchannel *)instance;
599         int ret;
600         unsigned char buffer[2048+MISDN_HEADER_LEN];
601         struct mISDNhead *hh = (struct mISDNhead *)buffer;
602
603         ret = recv(bchannel->b_sock, buffer, sizeof(buffer), 0);
604         if (ret >= (int)MISDN_HEADER_LEN) {
605                 switch(hh->prim) {
606                         /* after a confim, we can send more from queue */
607                         case PH_DATA_CNF:
608                         if (bchannel->nodsp_queue) {
609                                 bchannel->queue_sent = 0;
610                                 bchannel_send_queue(bchannel);
611                         }
612                         break;
613
614                         /* we receive audio data, we respond to it AND we send tones */
615                         case PH_DATA_IND:
616                         case PH_DATA_REQ:
617                         case DL_DATA_IND:
618                         case PH_CONTROL_IND:
619                         bchannel_receive(bchannel, buffer, ret-MISDN_HEADER_LEN);
620                         break;
621
622                         case PH_ACTIVATE_IND:
623                         case DL_ESTABLISH_IND:
624                         case PH_ACTIVATE_CNF:
625                         case DL_ESTABLISH_CNF:
626                         CDEBUG(bchannel->call, NULL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", bchannel->b_sock);
627                         bchannel_activated(bchannel);
628                         break;
629
630                         case PH_DEACTIVATE_IND:
631                         case DL_RELEASE_IND:
632                         case PH_DEACTIVATE_CNF:
633                         case DL_RELEASE_CNF:
634                         CDEBUG(bchannel->call, NULL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", bchannel->b_sock);
635 //                                      bchannel_deactivated(bchannel);
636                         break;
637
638                         default:
639                         CERROR(bchannel->call, NULL, "child message not handled: prim(0x%x) socket(%d) data len(%d)\n", hh->prim, bchannel->b_sock, ret - MISDN_HEADER_LEN);
640                 }
641         } else {
642 //              if (ret < 0 && errno != EWOULDBLOCK)
643                 CERROR(bchannel->call, NULL, "Read from socket %d failed with return code %d\n", bchannel->b_sock, ret);
644         }
645
646         /* if we received at least one b-frame, we will return 1 */
647         return 0;
648 }
649
650
651 /*
652  * bchannel channel handling
653  */
654 struct bchannel *bchannel_first = NULL;
655 struct bchannel *find_bchannel_handle(unsigned int handle)
656 {
657         struct bchannel *bchannel = bchannel_first;
658
659         while(bchannel) {
660                 if (bchannel->handle == handle)
661                         break;
662                 bchannel = bchannel->next;
663         }
664         return bchannel;
665 }
666
667 #if 0
668 struct bchannel *find_bchannel_ref(unsigned int ref)
669 {
670         struct bchannel *bchannel = bchannel_first;
671
672         while(bchannel) {
673                 if (bchannel->ref == ref)
674                         break;
675                 bchannel = bchannel->next;
676         }
677         return bchannel;
678 }
679 #endif
680
681 struct bchannel *alloc_bchannel(unsigned int handle)
682 {
683         struct bchannel **bchannelp = &bchannel_first;
684
685         while(*bchannelp)
686                 bchannelp = &((*bchannelp)->next);
687
688         *bchannelp = (struct bchannel *)calloc(1, sizeof(struct bchannel));
689         if (!*bchannelp)
690                 return NULL;
691         (*bchannelp)->handle = handle;
692         (*bchannelp)->b_state = BSTATE_IDLE;
693         (*bchannelp)->b_sock = -1;
694                 
695         return *bchannelp;
696 }
697
698 void free_bchannel(struct bchannel *bchannel)
699 {
700         struct bchannel **temp = &bchannel_first;
701
702         while(*temp) {
703                 if (*temp == bchannel) {
704                         *temp = (*temp)->next;
705                         if (bchannel->b_sock > -1)
706                                 bchannel_destroy(bchannel);
707                         if (bchannel->call) {
708                                 if (bchannel->call->bchannel)
709                                         bchannel->call->bchannel = NULL;
710                         }
711                         free(bchannel);
712                         return;
713                 }
714                 temp = &((*temp)->next);
715         }
716 }
717
718