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