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