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