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