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