dfbce5722e57e6b9cbc94c811b2ff4de1e0abd3c
[asterisk/asterisk.git] / channels / chan_alsa.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Copyright (C) 2002, Linux Support Services
5  *
6  * By Matthew Fredrickson <creslin@linux-support.net>
7  *
8  * This program is free software, distributed under the terms of
9  * the GNU General Public License
10  */
11
12 #include <asterisk/frame.h>
13 #include <asterisk/logger.h>
14 #include <asterisk/channel.h>
15 #include <asterisk/module.h>
16 #include <asterisk/channel_pvt.h>
17 #include <asterisk/options.h>
18 #include <asterisk/pbx.h>
19 #include <asterisk/config.h>
20 #include <asterisk/cli.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <sys/ioctl.h>
25 #include <sys/time.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <alsa/asoundlib.h>
30 #include "busy.h"
31 #include "ringtone.h"
32 #include "ring10.h"
33 #include "answer.h"
34
35 #ifdef ALSA_MONITOR
36 #include "alsa-monitor.h"
37 #endif
38
39 #define DEBUG 0
40 /* Which device to use */
41 #define ALSA_INDEV "default"
42 #define ALSA_OUTDEV "default"
43 #define DESIRED_RATE 8000
44
45 /* Lets use 160 sample frames, just like GSM.  */
46 #define FRAME_SIZE 160
47 #define PERIOD_FRAMES 80 /* 80 Frames, at 2 bytes each */
48
49 /* When you set the frame size, you have to come up with
50    the right buffer format as well. */
51 /* 5 64-byte frames = one frame */
52 #define BUFFER_FMT ((buffersize * 10) << 16) | (0x0006);
53
54 /* Don't switch between read/write modes faster than every 300 ms */
55 #define MIN_SWITCH_TIME 600
56
57 static snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
58 //static int block = O_NONBLOCK;
59 static char indevname[50] = ALSA_INDEV;
60 static char outdevname[50] = ALSA_OUTDEV;
61
62 static struct timeval lasttime;
63
64 static int usecnt;
65 static int needanswer = 0;
66 static int needringing = 0;
67 static int needhangup = 0;
68 static int silencesuppression = 0;
69 static int silencethreshold = 1000;
70
71 static char digits[80] = "";
72 static char text2send[80] = "";
73
74 static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
75
76 static char *type = "Console";
77 static char *desc = "ALSA Console Channel Driver";
78 static char *tdesc = "ALSA Console Channel Driver";
79 static char *config = "alsa.conf";
80
81 static char context[AST_MAX_EXTENSION] = "default";
82 static char language[MAX_LANGUAGE] = "";
83 static char exten[AST_MAX_EXTENSION] = "s";
84
85 /* Command pipe */
86 static int cmd[2];
87
88 int hookstate=0;
89
90 static short silence[FRAME_SIZE] = {0, };
91
92 struct sound {
93         int ind;
94         short *data;
95         int datalen;
96         int samplen;
97         int silencelen;
98         int repeat;
99 };
100
101 static struct sound sounds[] = {
102         { AST_CONTROL_RINGING, ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
103         { AST_CONTROL_BUSY, busy, sizeof(busy)/2, 4000, 4000, 1 },
104         { AST_CONTROL_CONGESTION, busy, sizeof(busy)/2, 2000, 2000, 1 },
105         { AST_CONTROL_RING, ring10, sizeof(ring10)/2, 16000, 32000, 1 },
106         { AST_CONTROL_ANSWER, answer, sizeof(answer)/2, 2200, 0, 0 },
107 };
108
109 /* Sound command pipe */
110 static int sndcmd[2];
111
112 static struct chan_alsa_pvt {
113         /* We only have one ALSA structure -- near sighted perhaps, but it
114            keeps this driver as simple as possible -- as it should be. */
115         struct ast_channel *owner;
116         char exten[AST_MAX_EXTENSION];
117         char context[AST_MAX_EXTENSION];
118 #if 0
119         snd_pcm_t *card;
120 #endif
121         snd_pcm_t *icard, *ocard;
122         
123 } alsa;
124
125 static int time_has_passed(void)
126 {
127         struct timeval tv;
128         int ms;
129         gettimeofday(&tv, NULL);
130         ms = (tv.tv_sec - lasttime.tv_sec) * 1000 +
131                         (tv.tv_usec - lasttime.tv_usec) / 1000;
132         if (ms > MIN_SWITCH_TIME)
133                 return -1;
134         return 0;
135 }
136
137 /* Number of buffers...  Each is FRAMESIZE/8 ms long.  For example
138    with 160 sample frames, and a buffer size of 3, we have a 60ms buffer, 
139    usually plenty. */
140
141 pthread_t sthread;
142
143 #define MAX_BUFFER_SIZE 100
144 //static int buffersize = 3;
145
146 //static int full_duplex = 0;
147
148 /* Are we reading or writing (simulated full duplex) */
149 //static int readmode = 1;
150
151 /* File descriptors for sound device */
152 static int readdev = -1;
153 static int writedev = -1;
154
155 static int autoanswer = 1;
156  
157 static int calc_loudness(short *frame)
158 {
159         int sum = 0;
160         int x;
161         for (x=0;x<FRAME_SIZE;x++) {
162                 if (frame[x] < 0)
163                         sum -= frame[x];
164                 else
165                         sum += frame[x];
166         }
167         sum = sum/FRAME_SIZE;
168         return sum;
169 }
170
171 static int cursound = -1;
172 static int sampsent = 0;
173 static int silencelen=0;
174 static int offset=0;
175 static int nosound=0;
176
177 static int send_sound(void)
178 {
179         short myframe[FRAME_SIZE];
180         int total = FRAME_SIZE;
181         short *frame = NULL;
182         int amt=0;
183         int res;
184         int myoff;
185         snd_pcm_state_t state;
186
187         if (cursound > -1) {
188                 res = total;
189                 if (sampsent < sounds[cursound].samplen) {
190                         myoff=0;
191                         while(total) {
192                                 amt = total;
193                                 if (amt > (sounds[cursound].datalen - offset)) 
194                                         amt = sounds[cursound].datalen - offset;
195                                 memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
196                                 total -= amt;
197                                 offset += amt;
198                                 sampsent += amt;
199                                 myoff += amt;
200                                 if (offset >= sounds[cursound].datalen)
201                                         offset = 0;
202                         }
203                         /* Set it up for silence */
204                         if (sampsent >= sounds[cursound].samplen) 
205                                 silencelen = sounds[cursound].silencelen;
206                         frame = myframe;
207                 } else {
208                         if (silencelen > 0) {
209                                 frame = silence;
210                                 silencelen -= res;
211                         } else {
212                                 if (sounds[cursound].repeat) {
213                                         /* Start over */
214                                         sampsent = 0;
215                                         offset = 0;
216                                 } else {
217                                         cursound = -1;
218                                         nosound = 0;
219                                 }
220                         return 0;
221                         }
222                 }
223                 
224                 if (res == 0 || !frame) {
225                         return 0;
226                 }
227 #ifdef ALSA_MONITOR
228                 alsa_monitor_write((char *)frame, res * 2);
229 #endif          
230                 state = snd_pcm_state(alsa.ocard);
231                 if (state == SND_PCM_STATE_XRUN) {
232                         snd_pcm_prepare(alsa.ocard);
233                 }
234                 res = snd_pcm_writei(alsa.ocard, frame, res);
235                 if (res > 0)
236                         return 0;
237                 return 0;
238         }
239         return 0;
240 }
241
242 static void *sound_thread(void *unused)
243 {
244         fd_set rfds;
245         fd_set wfds;
246         int max;
247         int res;
248         for(;;) {
249                 FD_ZERO(&rfds);
250                 FD_ZERO(&wfds);
251                 max = sndcmd[0];
252                 FD_SET(sndcmd[0], &rfds);
253                 if (cursound > -1) {
254                         FD_SET(writedev, &wfds);
255                         if (writedev > max)
256                                 max = writedev;
257                 }
258 #ifdef ALSA_MONITOR
259                 if (!alsa.owner) {
260                         FD_SET(readdev, &rfds);
261                         if (readdev > max)
262                                 max = readdev;
263                 }
264 #endif
265                 res = ast_select(max + 1, &rfds, &wfds, NULL, NULL);
266                 if (res < 1) {
267                         ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
268                         continue;
269                 }
270 #ifdef ALSA_MONITOR
271                 if (FD_ISSET(readdev, &rfds)) {
272                         /* Keep the pipe going with read audio */
273                         snd_pcm_state_t state;
274                         short buf[FRAME_SIZE];
275                         int r;
276                         
277                         state = snd_pcm_state(alsa.ocard);
278                         if (state == SND_PCM_STATE_XRUN) {
279                                 snd_pcm_prepare(alsa.ocard);
280                         }
281                         r = snd_pcm_readi(alsa.icard, buf, FRAME_SIZE);
282                         if (r == -EPIPE) {
283 #if DEBUG
284                                 ast_log(LOG_ERROR, "XRUN read\n");
285 #endif
286                                 snd_pcm_prepare(alsa.icard);
287                         } else if (r == -ESTRPIPE) {
288                                 ast_log(LOG_ERROR, "-ESTRPIPE\n");
289                                 snd_pcm_prepare(alsa.icard);
290                         } else if (r < 0) {
291                                 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
292                         } else
293                                 alsa_monitor_read((char *)buf, r * 2);
294                 }               
295 #endif          
296                 if (FD_ISSET(sndcmd[0], &rfds)) {
297                         read(sndcmd[0], &cursound, sizeof(cursound));
298                         silencelen = 0;
299                         offset = 0;
300                         sampsent = 0;
301                 }
302                 if (FD_ISSET(writedev, &wfds))
303                         if (send_sound())
304                                 ast_log(LOG_WARNING, "Failed to write sound\n");
305         }
306         /* Never reached */
307         return NULL;
308 }
309
310 static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
311 {
312         int err;
313         snd_pcm_t *handle = NULL;
314         snd_pcm_hw_params_t *hwparams = NULL;
315         snd_pcm_sw_params_t *swparams = NULL;
316         struct pollfd pfd;
317         int period_size = PERIOD_FRAMES * 4;
318         //int period_bytes = 0;
319         int buffer_size = 0;
320         
321         unsigned int rate = DESIRED_RATE;
322         unsigned int per_min = 1;
323         //unsigned int per_max = 8;
324         snd_pcm_uframes_t start_threshold, stop_threshold;
325
326         err = snd_pcm_open(&handle, dev, stream, O_NONBLOCK);
327         if (err < 0) {
328                 ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err));
329                 return NULL;
330         } else {
331                 ast_log(LOG_DEBUG, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write");
332         }
333
334         snd_pcm_hw_params_alloca(&hwparams);
335         snd_pcm_hw_params_any(handle, hwparams);
336
337         err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
338         if (err < 0) {
339                 ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err));
340         }
341
342         err = snd_pcm_hw_params_set_format(handle, hwparams, format);
343         if (err < 0) {
344                 ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err));
345         }
346
347         err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
348         if (err < 0) {
349                 ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err));
350         }
351
352         rate = snd_pcm_hw_params_set_rate_near(handle, hwparams, rate, 0);
353
354         if (rate != DESIRED_RATE) {
355                 ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate);
356         }
357
358         err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, period_size, 0);
359         if (err < 0) {
360                 ast_log(LOG_ERROR, "period_size(%d frames) is bad: %s\n", period_size, snd_strerror(err));
361         } else {
362                 ast_log(LOG_DEBUG, "Period size is %d\n", err);
363         }
364         period_size = err;
365
366         buffer_size = 4096 * 2; //period_size * 16;
367         err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, buffer_size);
368         if (err < 0) {
369                 ast_log(LOG_WARNING, "Problem setting buffer size of %d: %s\n", buffer_size, snd_strerror(err));
370         } else {
371                 ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err);
372         }
373         buffer_size = err;
374
375         err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, 0);
376         if (err < 0) {
377                 ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err));
378         }
379
380 #if 0
381         err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0);
382         if (err < 0) {
383                 ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err));
384         }
385 #endif
386
387         err = snd_pcm_hw_params(handle, hwparams);
388         if (err < 0) {
389                 ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err));
390         }
391
392         snd_pcm_sw_params_alloca(&swparams);
393         snd_pcm_sw_params_current(handle, swparams);
394
395 #if 1
396         if (stream == SND_PCM_STREAM_PLAYBACK) {
397                 start_threshold = period_size;
398         } else {
399                 start_threshold = 1;
400         }
401
402         err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
403         if (err < 0) {
404                 ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err));
405         }
406 #endif
407
408 #if 1
409         if (stream == SND_PCM_STREAM_PLAYBACK) {
410                 stop_threshold = buffer_size;
411         } else {
412                 stop_threshold = buffer_size;
413         }
414         err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
415         if (err < 0) {
416                 ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err));
417         }
418 #endif
419 #if 0
420         err = snd_pcm_sw_params_set_xfer_align(handle, swparams, PERIOD_FRAMES);
421         if (err < 0) {
422                 ast_log(LOG_ERROR, "Unable to set xfer alignment: %s\n", snd_strerror(err));
423         }
424 #endif
425
426         err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, buffer_size);
427         if (err < 0) {
428                 ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err));
429         }
430
431         err = snd_pcm_sw_params(handle, swparams);
432         if (err < 0) {
433                 ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err));
434         }
435
436         err = snd_pcm_poll_descriptors_count(handle);
437         if (err <= 0) {
438                 ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err));
439         }
440
441         if (err != 1) {
442                 ast_log(LOG_DEBUG, "Can't handle more than one device\n");
443         }
444
445         snd_pcm_poll_descriptors(handle, &pfd, err);
446         ast_log(LOG_DEBUG, "Acquired fd %d from the poll descriptor\n", pfd.fd);
447
448         if (stream == SND_PCM_STREAM_CAPTURE)
449                 readdev = pfd.fd;
450         else
451                 writedev = pfd.fd;
452
453         return handle;
454 }
455
456 static int soundcard_init(void)
457 {
458         alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE);
459         alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK);
460
461         if (!alsa.icard || !alsa.ocard) {
462                 ast_log(LOG_ERROR, "Problem opening alsa I/O devices\n");
463                 return -1;
464         }
465
466         return readdev;
467 }
468
469 static int alsa_digit(struct ast_channel *c, char digit)
470 {
471         ast_verbose( " << Console Received digit %c >> \n", digit);
472         return 0;
473 }
474
475 static int alsa_text(struct ast_channel *c, char *text)
476 {
477         ast_verbose( " << Console Received text %s >> \n", text);
478         return 0;
479 }
480
481 static int alsa_call(struct ast_channel *c, char *dest, int timeout)
482 {
483         int res = 3;
484         ast_verbose( " << Call placed to '%s' on console >> \n", dest);
485         if (autoanswer) {
486                 ast_verbose( " << Auto-answered >> \n" );
487                 needanswer = 1;
488         } else {
489                 ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
490                 needringing = 1;
491                 write(sndcmd[1], &res, sizeof(res));
492         }
493         return 0;
494 }
495
496 static void answer_sound(void)
497 {
498         int res;
499         nosound = 1;
500         res = 4;
501         write(sndcmd[1], &res, sizeof(res));
502         
503 }
504
505 static int alsa_answer(struct ast_channel *c)
506 {
507         ast_verbose( " << Console call has been answered >> \n");
508         answer_sound();
509         ast_setstate(c, AST_STATE_UP);
510         cursound = -1;
511         return 0;
512 }
513
514 static int alsa_hangup(struct ast_channel *c)
515 {
516         int res;
517         cursound = -1;
518         c->pvt->pvt = NULL;
519         alsa.owner = NULL;
520         ast_verbose( " << Hangup on console >> \n");
521         ast_pthread_mutex_lock(&usecnt_lock);
522         usecnt--;
523         ast_pthread_mutex_unlock(&usecnt_lock);
524         needhangup = 0;
525         needanswer = 0;
526         if (hookstate) {
527                 res = 2;
528                 write(sndcmd[1], &res, sizeof(res));
529         }
530         return 0;
531 }
532
533 #if 0
534 static int soundcard_writeframe(short *data)
535 {       
536         /* Write an exactly FRAME_SIZE sized of frame */
537         static int bufcnt = 0;
538         static short buffer[FRAME_SIZE * MAX_BUFFER_SIZE * 5];
539         struct audio_buf_info info;
540         int res;
541         int fd = sounddev;
542         static int warned=0;
543         if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)) {
544                 if (!warned)
545                         ast_log(LOG_WARNING, "Error reading output space\n");
546                 bufcnt = buffersize;
547                 warned++;
548         }
549         if ((info.fragments >= buffersize * 5) && (bufcnt == buffersize)) {
550                 /* We've run out of stuff, buffer again */
551                 bufcnt = 0;
552         }
553         if (bufcnt == buffersize) {
554                 /* Write sample immediately */
555                 res = write(fd, ((void *)data), FRAME_SIZE * 2);
556         } else {
557                 /* Copy the data into our buffer */
558                 res = FRAME_SIZE * 2;
559                 memcpy(buffer + (bufcnt * FRAME_SIZE), data, FRAME_SIZE * 2);
560                 bufcnt++;
561                 if (bufcnt == buffersize) {
562                         res = write(fd, ((void *)buffer), FRAME_SIZE * 2 * buffersize);
563                 }
564         }
565         return res;
566 }
567 #endif
568
569 static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
570 {
571         int res;
572         static char sizbuf[8000];
573         static int sizpos = 0;
574         int len = sizpos;
575         int pos;
576         //size_t frames = 0;
577         snd_pcm_state_t state;
578         /* Immediately return if no sound is enabled */
579         if (nosound)
580                 return 0;
581         /* Stop any currently playing sound */
582         if (cursound != -1) {
583                 snd_pcm_drop(alsa.ocard);
584                 snd_pcm_prepare(alsa.ocard);
585                 cursound = -1;
586         }
587         
588
589         /* We have to digest the frame in 160-byte portions */
590         if (f->datalen > sizeof(sizbuf) - sizpos) {
591                 ast_log(LOG_WARNING, "Frame too large\n");
592                 return -1;
593         }
594         memcpy(sizbuf + sizpos, f->data, f->datalen);
595         len += f->datalen;
596         pos = 0;
597 #ifdef ALSA_MONITOR
598         alsa_monitor_write(sizbuf, len);
599 #endif
600         state = snd_pcm_state(alsa.ocard);
601         if (state == SND_PCM_STATE_XRUN) {
602                 snd_pcm_prepare(alsa.ocard);
603         }
604         res = snd_pcm_writei(alsa.ocard, sizbuf, len/2);
605         if (res == -EPIPE) {
606 #if DEBUG
607                 ast_log(LOG_DEBUG, "XRUN write\n");
608 #endif
609                 snd_pcm_prepare(alsa.ocard);
610                 res = snd_pcm_writei(alsa.ocard, sizbuf, len/2);
611                 if (res != len/2) {
612                         ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res));
613                         return -1;
614                 } else if (res < 0) {
615                         ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res));
616                         return -1;
617                 }
618         } else {
619                 if (res == -ESTRPIPE) {
620                         ast_log(LOG_ERROR, "You've got some big problems\n");
621                 }
622         }
623
624         return 0;
625 }
626
627
628 static struct ast_frame *alsa_read(struct ast_channel *chan)
629 {
630         static struct ast_frame f;
631         static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET/2];
632         short *buf;
633         static int readpos = 0;
634         static int left = FRAME_SIZE;
635         int res;
636         int b;
637         int nonull=0;
638         snd_pcm_state_t state;
639         int r = 0;
640         int off = 0;
641
642         /* Acknowledge any pending cmd */
643         res = read(cmd[0], &b, sizeof(b));
644         if (res > 0)
645                 nonull = 1;
646         
647         f.frametype = AST_FRAME_NULL;
648         f.subclass = 0;
649         f.samples = 0;
650         f.datalen = 0;
651         f.data = NULL;
652         f.offset = 0;
653         f.src = type;
654         f.mallocd = 0;
655         
656         if (needringing) {
657                 f.frametype = AST_FRAME_CONTROL;
658                 f.subclass = AST_CONTROL_RINGING;
659                 needringing = 0;
660                 return &f;
661         }
662         
663         if (needhangup) {
664                 needhangup = 0;
665                 return NULL;
666         }
667         if (strlen(text2send)) {
668                 f.frametype = AST_FRAME_TEXT;
669                 f.subclass = 0;
670                 f.data = text2send;
671                 f.datalen = strlen(text2send);
672                 strcpy(text2send,"");
673                 return &f;
674         }
675         if (strlen(digits)) {
676                 f.frametype = AST_FRAME_DTMF;
677                 f.subclass = digits[0];
678                 for (res=0;res<strlen(digits);res++)
679                         digits[res] = digits[res + 1];
680                 return &f;
681         }
682         
683         if (needanswer) {
684                 needanswer = 0;
685                 f.frametype = AST_FRAME_CONTROL;
686                 f.subclass = AST_CONTROL_ANSWER;
687                 ast_setstate(chan, AST_STATE_UP);
688                 return &f;
689         }
690         
691         if (nonull)
692                 return &f;
693                 
694         
695         state = snd_pcm_state(alsa.ocard);
696         if (state == SND_PCM_STATE_XRUN) {
697                 snd_pcm_prepare(alsa.ocard);
698         }
699
700         buf = __buf + AST_FRIENDLY_OFFSET/2;
701
702         r = snd_pcm_readi(alsa.icard, buf + readpos, left);
703         if (r == -EPIPE) {
704 #if DEBUG
705                 ast_log(LOG_ERROR, "XRUN read\n");
706 #endif
707                 snd_pcm_prepare(alsa.icard);
708         } else if (r == -ESTRPIPE) {
709                 ast_log(LOG_ERROR, "-ESTRPIPE\n");
710                 snd_pcm_prepare(alsa.icard);
711         } else if (r < 0) {
712                 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
713                 return NULL;
714         } else if (r >= 0) {
715                 off -= r;
716         }
717         /* Update positions */
718         readpos += r;
719         left -= r;
720
721         if (readpos >= FRAME_SIZE) {
722                 /* A real frame */
723                 readpos = 0;
724                 left = FRAME_SIZE;
725                 if (chan->_state != AST_STATE_UP) {
726                         /* Don't transmit unless it's up */
727                         return &f;
728                 }
729                 f.frametype = AST_FRAME_VOICE;
730                 f.subclass = AST_FORMAT_SLINEAR;
731                 f.samples = FRAME_SIZE;
732                 f.datalen = FRAME_SIZE * 2;
733                 f.data = buf;
734                 f.offset = AST_FRIENDLY_OFFSET;
735                 f.src = type;
736                 f.mallocd = 0;
737 #ifdef ALSA_MONITOR
738                 alsa_monitor_read((char *)buf, FRAME_SIZE * 2);
739 #endif          
740
741 #if 0
742                 { static int fd = -1;
743                   if (fd < 0)
744                         fd = open("output.raw", O_RDWR | O_TRUNC | O_CREAT);
745                   write(fd, f.data, f.datalen);
746                 }
747 #endif          
748         }
749         return &f;
750 }
751
752 static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
753 {
754         struct chan_alsa_pvt *p = newchan->pvt->pvt;
755         p->owner = newchan;
756         return 0;
757 }
758
759 static int alsa_indicate(struct ast_channel *chan, int cond)
760 {
761         int res;
762         switch(cond) {
763         case AST_CONTROL_BUSY:
764                 res = 1;
765                 break;
766         case AST_CONTROL_CONGESTION:
767                 res = 2;
768                 break;
769         case AST_CONTROL_RINGING:
770                 res = 0;
771                 break;
772         default:
773                 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
774                 return -1;
775         }
776         if (res > -1) {
777                 write(sndcmd[1], &res, sizeof(res));
778         }
779         return 0;       
780 }
781
782 static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
783 {
784         struct ast_channel *tmp;
785         tmp = ast_channel_alloc(0);
786         if (tmp) {
787                 snprintf(tmp->name, sizeof(tmp->name), "ALSA/%s", indevname);
788                 tmp->type = type;
789                 tmp->fds[0] = readdev;
790                 tmp->fds[1] = cmd[0];
791                 tmp->nativeformats = AST_FORMAT_SLINEAR;
792                 tmp->pvt->pvt = p;
793                 tmp->pvt->send_digit = alsa_digit;
794                 tmp->pvt->send_text = alsa_text;
795                 tmp->pvt->hangup = alsa_hangup;
796                 tmp->pvt->answer = alsa_answer;
797                 tmp->pvt->read = alsa_read;
798                 tmp->pvt->call = alsa_call;
799                 tmp->pvt->write = alsa_write;
800                 tmp->pvt->indicate = alsa_indicate;
801                 tmp->pvt->fixup = alsa_fixup;
802                 if (strlen(p->context))
803                         strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
804                 if (strlen(p->exten))
805                         strncpy(tmp->exten, p->exten, sizeof(tmp->exten)-1);
806                 if (strlen(language))
807                         strncpy(tmp->language, language, sizeof(tmp->language)-1);
808                 p->owner = tmp;
809                 ast_setstate(tmp, state);
810                 ast_pthread_mutex_lock(&usecnt_lock);
811                 usecnt++;
812                 ast_pthread_mutex_unlock(&usecnt_lock);
813                 ast_update_use_count();
814                 if (state != AST_STATE_DOWN) {
815                         if (ast_pbx_start(tmp)) {
816                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
817                                 ast_hangup(tmp);
818                                 tmp = NULL;
819                         }
820                 }
821         }
822         return tmp;
823 }
824
825 static struct ast_channel *alsa_request(char *type, int format, void *data)
826 {
827         int oldformat = format;
828         struct ast_channel *tmp;
829         format &= AST_FORMAT_SLINEAR;
830         if (!format) {
831                 ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat);
832                 return NULL;
833         }
834         if (alsa.owner) {
835                 ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
836                 return NULL;
837         }
838         tmp= alsa_new(&alsa, AST_STATE_DOWN);
839         if (!tmp) {
840                 ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
841         }
842         return tmp;
843 }
844
845 static int console_autoanswer(int fd, int argc, char *argv[])
846 {
847         if ((argc != 1) && (argc != 2))
848                 return RESULT_SHOWUSAGE;
849         if (argc == 1) {
850                 ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
851                 return RESULT_SUCCESS;
852         } else {
853                 if (!strcasecmp(argv[1], "on"))
854                         autoanswer = -1;
855                 else if (!strcasecmp(argv[1], "off"))
856                         autoanswer = 0;
857                 else
858                         return RESULT_SHOWUSAGE;
859         }
860         return RESULT_SUCCESS;
861 }
862
863 static char *autoanswer_complete(char *line, char *word, int pos, int state)
864 {
865 #ifndef MIN
866 #define MIN(a,b) ((a) < (b) ? (a) : (b))
867 #endif
868         switch(state) {
869         case 0:
870                 if (strlen(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
871                         return strdup("on");
872         case 1:
873                 if (strlen(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
874                         return strdup("off");
875         default:
876                 return NULL;
877         }
878         return NULL;
879 }
880
881 static char autoanswer_usage[] =
882 "Usage: autoanswer [on|off]\n"
883 "       Enables or disables autoanswer feature.  If used without\n"
884 "       argument, displays the current on/off status of autoanswer.\n"
885 "       The default value of autoanswer is in 'alsa.conf'.\n";
886
887 static int console_answer(int fd, int argc, char *argv[])
888 {
889         if (argc != 1)
890                 return RESULT_SHOWUSAGE;
891         if (!alsa.owner) {
892                 ast_cli(fd, "No one is calling us\n");
893                 return RESULT_FAILURE;
894         }
895         hookstate = 1;
896         cursound = -1;
897         needanswer++;
898         answer_sound();
899         return RESULT_SUCCESS;
900 }
901
902 static char sendtext_usage[] =
903 "Usage: send text <message>\n"
904 "       Sends a text message for display on the remote terminal.\n";
905
906 static int console_sendtext(int fd, int argc, char *argv[])
907 {
908         int tmparg = 2;
909         if (argc < 2)
910                 return RESULT_SHOWUSAGE;
911         if (!alsa.owner) {
912                 ast_cli(fd, "No one is calling us\n");
913                 return RESULT_FAILURE;
914         }
915         if (strlen(text2send))
916                 ast_cli(fd, "Warning: message already waiting to be sent, overwriting\n");
917         strcpy(text2send, "");
918         while(tmparg <= argc) {
919                 strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send));
920                 strncat(text2send, " ", sizeof(text2send) - strlen(text2send));
921         }
922         needanswer++;
923         return RESULT_SUCCESS;
924 }
925
926 static char answer_usage[] =
927 "Usage: answer\n"
928 "       Answers an incoming call on the console (ALSA) channel.\n";
929
930 static int console_hangup(int fd, int argc, char *argv[])
931 {
932         if (argc != 1)
933                 return RESULT_SHOWUSAGE;
934         cursound = -1;
935         if (!alsa.owner && !hookstate) {
936                 ast_cli(fd, "No call to hangup up\n");
937                 return RESULT_FAILURE;
938         }
939         hookstate = 0;
940         if (alsa.owner)
941                 needhangup++;
942         return RESULT_SUCCESS;
943 }
944
945 static char hangup_usage[] =
946 "Usage: hangup\n"
947 "       Hangs up any call currently placed on the console.\n";
948
949
950 static int console_dial(int fd, int argc, char *argv[])
951 {
952         char tmp[256], *tmp2;
953         char *mye, *myc;
954         int b = 0;
955         if ((argc != 1) && (argc != 2))
956                 return RESULT_SHOWUSAGE;
957         if (alsa.owner) {
958                 if (argc == 2) {
959                         strncat(digits, argv[1], sizeof(digits) - strlen(digits));
960                         /* Wake up the polling thread */
961                         write(cmd[1], &b, sizeof(b));
962                 } else {
963                         ast_cli(fd, "You're already in a call.  You can use this only to dial digits until you hangup\n");
964                         return RESULT_FAILURE;
965                 }
966                 return RESULT_SUCCESS;
967         }
968         mye = exten;
969         myc = context;
970         if (argc == 2) {
971                 char *stringp=NULL;
972                 strncpy(tmp, argv[1], sizeof(tmp)-1);
973                 stringp=tmp;
974                 strsep(&stringp, "@");
975                 tmp2 = strsep(&stringp, "@");
976                 if (strlen(tmp))
977                         mye = tmp;
978                 if (tmp2 && strlen(tmp2))
979                         myc = tmp2;
980         }
981         if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
982                 strncpy(alsa.exten, mye, sizeof(alsa.exten)-1);
983                 strncpy(alsa.context, myc, sizeof(alsa.context)-1);
984                 hookstate = 1;
985                 alsa_new(&alsa, AST_STATE_UP);
986         } else
987                 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
988         return RESULT_SUCCESS;
989 }
990
991 static char dial_usage[] =
992 "Usage: dial [extension[@context]]\n"
993 "       Dials a given extensison (";
994
995
996 static struct ast_cli_entry myclis[] = {
997         { { "answer", NULL }, console_answer, "Answer an incoming console call", answer_usage },
998         { { "hangup", NULL }, console_hangup, "Hangup a call on the console", hangup_usage },
999         { { "dial", NULL }, console_dial, "Dial an extension on the console", dial_usage },
1000         { { "send", "text", NULL }, console_sendtext, "Send text to the remote device", sendtext_usage },
1001         { { "autoanswer", NULL }, console_autoanswer, "Sets/displays autoanswer", autoanswer_usage, autoanswer_complete }
1002 };
1003
1004 int load_module()
1005 {
1006         int res;
1007         int x;
1008         int flags;
1009         struct ast_config *cfg;
1010         struct ast_variable *v;
1011         res = pipe(cmd);
1012         res = pipe(sndcmd);
1013         if (res) {
1014                 ast_log(LOG_ERROR, "Unable to create pipe\n");
1015                 return -1;
1016         }
1017         flags = fcntl(cmd[0], F_GETFL);
1018         fcntl(cmd[0], F_SETFL, flags | O_NONBLOCK);
1019         flags = fcntl(cmd[1], F_GETFL);
1020         fcntl(cmd[1], F_SETFL, flags | O_NONBLOCK);
1021         res = soundcard_init();
1022         if (res < 0) {
1023                 close(cmd[1]);
1024                 close(cmd[0]);
1025                 if (option_verbose > 1) {
1026                         ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
1027                         ast_verbose(VERBOSE_PREFIX_2 "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
1028                 }
1029                 return 0;
1030         }
1031 #if 0
1032         if (!full_duplex)
1033                 ast_log(LOG_WARNING, "XXX I don't work right with non-full duplex sound cards XXX\n");
1034 #endif
1035         res = ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR, alsa_request);
1036         if (res < 0) {
1037                 ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", type);
1038                 return -1;
1039         }
1040         for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
1041                 ast_cli_register(myclis + x);
1042         if ((cfg = ast_load(config))) {
1043                 v = ast_variable_browse(cfg, "general");
1044                 while(v) {
1045                         if (!strcasecmp(v->name, "autoanswer"))
1046                                 autoanswer = ast_true(v->value);
1047                         else if (!strcasecmp(v->name, "silencesuppression"))
1048                                 silencesuppression = ast_true(v->value);
1049                         else if (!strcasecmp(v->name, "silencethreshold"))
1050                                 silencethreshold = atoi(v->value);
1051                         else if (!strcasecmp(v->name, "context"))
1052                                 strncpy(context, v->value, sizeof(context)-1);
1053                         else if (!strcasecmp(v->name, "language"))
1054                                 strncpy(language, v->value, sizeof(language)-1);
1055                         else if (!strcasecmp(v->name, "extension"))
1056                                 strncpy(exten, v->value, sizeof(exten)-1);
1057                         else if (!strcasecmp(v->name, "input_device"))
1058                                 strncpy(indevname, v->value, sizeof(indevname)-1);
1059                         else if (!strcasecmp(v->name, "output_device"))
1060                                 strncpy(outdevname, v->value, sizeof(outdevname)-1);
1061                         v=v->next;
1062                 }
1063                 ast_destroy(cfg);
1064         }
1065         pthread_create(&sthread, NULL, sound_thread, NULL);
1066 #ifdef ALSA_MONITOR
1067         if (alsa_monitor_start()) {
1068                 ast_log(LOG_ERROR, "Problem starting Monitoring\n");
1069         }
1070 #endif   
1071         return 0;
1072 }
1073
1074
1075
1076 int unload_module()
1077 {
1078         int x;
1079         for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
1080                 ast_cli_unregister(myclis + x);
1081         close(readdev);
1082         close(writedev);
1083         if (cmd[0] > 0) {
1084                 close(cmd[0]);
1085                 close(cmd[1]);
1086         }
1087         if (sndcmd[0] > 0) {
1088                 close(sndcmd[0]);
1089                 close(sndcmd[1]);
1090         }
1091         if (alsa.owner)
1092                 ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
1093         if (alsa.owner)
1094                 return -1;
1095         return 0;
1096 }
1097
1098 char *description()
1099 {
1100         return desc;
1101 }
1102
1103 int usecount()
1104 {
1105         int res;
1106         ast_pthread_mutex_lock(&usecnt_lock);
1107         res = usecnt;
1108         ast_pthread_mutex_unlock(&usecnt_lock);
1109         return res;
1110 }
1111
1112 char *key()
1113 {
1114         return ASTERISK_GPL_KEY;
1115 }