don't allow string input to overrun the buffer to hold it (ASA-2007-010)
[asterisk-bristuff.git] / channels / chan_alsa.c
blobb64cd941ef157ea7ead6c4d177dcb6fb1febd968
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * By Matthew Fredrickson <creslin@digium.com>
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.
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.
19 /*! \file
20 * \brief ALSA sound card channel driver
22 * \author Matthew Fredrickson <creslin@digium.com>
24 * \par See also
25 * \arg Config_alsa
27 * \ingroup channel_drivers
30 /*** MODULEINFO
31 <depend>asound</depend>
32 ***/
34 #include "asterisk.h"
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <errno.h>
41 #include <sys/ioctl.h>
42 #include <sys/time.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <stdio.h>
47 #define ALSA_PCM_NEW_HW_PARAMS_API
48 #define ALSA_PCM_NEW_SW_PARAMS_API
49 #include <alsa/asoundlib.h>
51 #include "asterisk/frame.h"
52 #include "asterisk/logger.h"
53 #include "asterisk/channel.h"
54 #include "asterisk/module.h"
55 #include "asterisk/options.h"
56 #include "asterisk/pbx.h"
57 #include "asterisk/config.h"
58 #include "asterisk/cli.h"
59 #include "asterisk/utils.h"
60 #include "asterisk/causes.h"
61 #include "asterisk/endian.h"
62 #include "asterisk/stringfields.h"
63 #include "asterisk/abstract_jb.h"
64 #include "asterisk/musiconhold.h"
66 #include "busy.h"
67 #include "ringtone.h"
68 #include "ring10.h"
69 #include "answer.h"
71 #ifdef ALSA_MONITOR
72 #include "alsa-monitor.h"
73 #endif
75 /*! Global jitterbuffer configuration - by default, jb is disabled */
76 static struct ast_jb_conf default_jbconf = {
77 .flags = 0,
78 .max_size = -1,
79 .resync_threshold = -1,
80 .impl = ""
82 static struct ast_jb_conf global_jbconf;
84 #define DEBUG 0
85 /* Which device to use */
86 #define ALSA_INDEV "default"
87 #define ALSA_OUTDEV "default"
88 #define DESIRED_RATE 8000
90 /* Lets use 160 sample frames, just like GSM. */
91 #define FRAME_SIZE 160
92 #define PERIOD_FRAMES 80 /* 80 Frames, at 2 bytes each */
94 /* When you set the frame size, you have to come up with
95 the right buffer format as well. */
96 /* 5 64-byte frames = one frame */
97 #define BUFFER_FMT ((buffersize * 10) << 16) | (0x0006);
99 /* Don't switch between read/write modes faster than every 300 ms */
100 #define MIN_SWITCH_TIME 600
102 #if __BYTE_ORDER == __LITTLE_ENDIAN
103 static snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
104 #else
105 static snd_pcm_format_t format = SND_PCM_FORMAT_S16_BE;
106 #endif
108 /* static int block = O_NONBLOCK; */
109 static char indevname[50] = ALSA_INDEV;
110 static char outdevname[50] = ALSA_OUTDEV;
112 #if 0
113 static struct timeval lasttime;
114 #endif
116 static int silencesuppression = 0;
117 static int silencethreshold = 1000;
119 AST_MUTEX_DEFINE_STATIC(alsalock);
121 static const char tdesc[] = "ALSA Console Channel Driver";
122 static const char config[] = "alsa.conf";
124 static char context[AST_MAX_CONTEXT] = "default";
125 static char language[MAX_LANGUAGE] = "";
126 static char exten[AST_MAX_EXTENSION] = "s";
127 static char mohinterpret[MAX_MUSICCLASS];
129 static int hookstate = 0;
131 static short silence[FRAME_SIZE] = { 0, };
133 struct sound {
134 int ind;
135 short *data;
136 int datalen;
137 int samplen;
138 int silencelen;
139 int repeat;
142 static struct sound sounds[] = {
143 {AST_CONTROL_RINGING, ringtone, sizeof(ringtone) / 2, 16000, 32000, 1},
144 {AST_CONTROL_BUSY, busy, sizeof(busy) / 2, 4000, 4000, 1},
145 {AST_CONTROL_CONGESTION, busy, sizeof(busy) / 2, 2000, 2000, 1},
146 {AST_CONTROL_RING, ring10, sizeof(ring10) / 2, 16000, 32000, 1},
147 {AST_CONTROL_ANSWER, answer, sizeof(answer) / 2, 2200, 0, 0},
150 /* Sound command pipe */
151 static int sndcmd[2];
153 static struct chan_alsa_pvt {
154 /* We only have one ALSA structure -- near sighted perhaps, but it
155 keeps this driver as simple as possible -- as it should be. */
156 struct ast_channel *owner;
157 char exten[AST_MAX_EXTENSION];
158 char context[AST_MAX_CONTEXT];
159 #if 0
160 snd_pcm_t *card;
161 #endif
162 snd_pcm_t *icard, *ocard;
164 } alsa;
166 /* Number of buffers... Each is FRAMESIZE/8 ms long. For example
167 with 160 sample frames, and a buffer size of 3, we have a 60ms buffer,
168 usually plenty. */
170 pthread_t sthread;
172 #define MAX_BUFFER_SIZE 100
174 /* File descriptors for sound device */
175 static int readdev = -1;
176 static int writedev = -1;
178 static int autoanswer = 1;
180 static int cursound = -1;
181 static int sampsent = 0;
182 static int silencelen = 0;
183 static int offset = 0;
184 static int nosound = 0;
186 /* ZZ */
187 static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause);
188 static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration);
189 static int alsa_text(struct ast_channel *c, const char *text);
190 static int alsa_hangup(struct ast_channel *c);
191 static int alsa_answer(struct ast_channel *c);
192 static struct ast_frame *alsa_read(struct ast_channel *chan);
193 static int alsa_call(struct ast_channel *c, char *dest, int timeout);
194 static int alsa_write(struct ast_channel *chan, struct ast_frame *f);
195 static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
196 static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
198 static const struct ast_channel_tech alsa_tech = {
199 .type = "Console",
200 .description = tdesc,
201 .capabilities = AST_FORMAT_SLINEAR,
202 .requester = alsa_request,
203 .send_digit_end = alsa_digit,
204 .send_text = alsa_text,
205 .hangup = alsa_hangup,
206 .answer = alsa_answer,
207 .read = alsa_read,
208 .call = alsa_call,
209 .write = alsa_write,
210 .indicate = alsa_indicate,
211 .fixup = alsa_fixup,
214 static int send_sound(void)
216 short myframe[FRAME_SIZE];
217 int total = FRAME_SIZE;
218 short *frame = NULL;
219 int amt = 0, res, myoff;
220 snd_pcm_state_t state;
222 if (cursound == -1)
223 return 0;
225 res = total;
226 if (sampsent < sounds[cursound].samplen) {
227 myoff = 0;
228 while (total) {
229 amt = total;
230 if (amt > (sounds[cursound].datalen - offset))
231 amt = sounds[cursound].datalen - offset;
232 memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
233 total -= amt;
234 offset += amt;
235 sampsent += amt;
236 myoff += amt;
237 if (offset >= sounds[cursound].datalen)
238 offset = 0;
240 /* Set it up for silence */
241 if (sampsent >= sounds[cursound].samplen)
242 silencelen = sounds[cursound].silencelen;
243 frame = myframe;
244 } else {
245 if (silencelen > 0) {
246 frame = silence;
247 silencelen -= res;
248 } else {
249 if (sounds[cursound].repeat) {
250 /* Start over */
251 sampsent = 0;
252 offset = 0;
253 } else {
254 cursound = -1;
255 nosound = 0;
257 return 0;
261 if (res == 0 || !frame)
262 return 0;
264 #ifdef ALSA_MONITOR
265 alsa_monitor_write((char *) frame, res * 2);
266 #endif
267 state = snd_pcm_state(alsa.ocard);
268 if (state == SND_PCM_STATE_XRUN)
269 snd_pcm_prepare(alsa.ocard);
270 res = snd_pcm_writei(alsa.ocard, frame, res);
271 if (res > 0)
272 return 0;
273 return 0;
276 static void *sound_thread(void *unused)
278 fd_set rfds;
279 fd_set wfds;
280 int max, res;
282 for (;;) {
283 FD_ZERO(&rfds);
284 FD_ZERO(&wfds);
285 max = sndcmd[0];
286 FD_SET(sndcmd[0], &rfds);
287 if (cursound > -1) {
288 FD_SET(writedev, &wfds);
289 if (writedev > max)
290 max = writedev;
292 #ifdef ALSA_MONITOR
293 if (!alsa.owner) {
294 FD_SET(readdev, &rfds);
295 if (readdev > max)
296 max = readdev;
298 #endif
299 res = ast_select(max + 1, &rfds, &wfds, NULL, NULL);
300 if (res < 1) {
301 ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
302 continue;
304 #ifdef ALSA_MONITOR
305 if (FD_ISSET(readdev, &rfds)) {
306 /* Keep the pipe going with read audio */
307 snd_pcm_state_t state;
308 short buf[FRAME_SIZE];
309 int r;
311 state = snd_pcm_state(alsa.ocard);
312 if (state == SND_PCM_STATE_XRUN) {
313 snd_pcm_prepare(alsa.ocard);
315 r = snd_pcm_readi(alsa.icard, buf, FRAME_SIZE);
316 if (r == -EPIPE) {
317 #if DEBUG
318 ast_log(LOG_ERROR, "XRUN read\n");
319 #endif
320 snd_pcm_prepare(alsa.icard);
321 } else if (r == -ESTRPIPE) {
322 ast_log(LOG_ERROR, "-ESTRPIPE\n");
323 snd_pcm_prepare(alsa.icard);
324 } else if (r < 0) {
325 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
326 } else
327 alsa_monitor_read((char *) buf, r * 2);
329 #endif
330 if (FD_ISSET(sndcmd[0], &rfds)) {
331 read(sndcmd[0], &cursound, sizeof(cursound));
332 silencelen = 0;
333 offset = 0;
334 sampsent = 0;
336 if (FD_ISSET(writedev, &wfds))
337 if (send_sound())
338 ast_log(LOG_WARNING, "Failed to write sound\n");
340 /* Never reached */
341 return NULL;
344 static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
346 int err;
347 int direction;
348 snd_pcm_t *handle = NULL;
349 snd_pcm_hw_params_t *hwparams = NULL;
350 snd_pcm_sw_params_t *swparams = NULL;
351 struct pollfd pfd;
352 snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4;
353 /* int period_bytes = 0; */
354 snd_pcm_uframes_t buffer_size = 0;
356 unsigned int rate = DESIRED_RATE;
357 #if 0
358 unsigned int per_min = 1;
359 #endif
360 /* unsigned int per_max = 8; */
361 snd_pcm_uframes_t start_threshold, stop_threshold;
363 err = snd_pcm_open(&handle, dev, stream, O_NONBLOCK);
364 if (err < 0) {
365 ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err));
366 return NULL;
367 } else
368 ast_log(LOG_DEBUG, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write");
370 snd_pcm_hw_params_alloca(&hwparams);
371 snd_pcm_hw_params_any(handle, hwparams);
373 err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
374 if (err < 0)
375 ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err));
377 err = snd_pcm_hw_params_set_format(handle, hwparams, format);
378 if (err < 0)
379 ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err));
381 err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
382 if (err < 0)
383 ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err));
385 direction = 0;
386 err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction);
387 if (rate != DESIRED_RATE)
388 ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate);
390 direction = 0;
391 err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction);
392 if (err < 0)
393 ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err));
394 else
395 ast_log(LOG_DEBUG, "Period size is %d\n", err);
397 buffer_size = 4096 * 2; /* period_size * 16; */
398 err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
399 if (err < 0)
400 ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err));
401 else
402 ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err);
404 #if 0
405 direction = 0;
406 err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, &direction);
407 if (err < 0)
408 ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err));
410 err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0);
411 if (err < 0)
412 ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err));
413 #endif
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));
419 snd_pcm_sw_params_alloca(&swparams);
420 snd_pcm_sw_params_current(handle, swparams);
422 #if 1
423 if (stream == SND_PCM_STREAM_PLAYBACK)
424 start_threshold = period_size;
425 else
426 start_threshold = 1;
428 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
429 if (err < 0)
430 ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err));
431 #endif
433 #if 1
434 if (stream == SND_PCM_STREAM_PLAYBACK)
435 stop_threshold = buffer_size;
436 else
437 stop_threshold = buffer_size;
439 err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
440 if (err < 0)
441 ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err));
442 #endif
443 #if 0
444 err = snd_pcm_sw_params_set_xfer_align(handle, swparams, PERIOD_FRAMES);
445 if (err < 0)
446 ast_log(LOG_ERROR, "Unable to set xfer alignment: %s\n", snd_strerror(err));
447 #endif
449 #if 0
450 err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, silencethreshold);
451 if (err < 0)
452 ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err));
453 #endif
454 err = snd_pcm_sw_params(handle, swparams);
455 if (err < 0)
456 ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err));
458 err = snd_pcm_poll_descriptors_count(handle);
459 if (err <= 0)
460 ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err));
461 if (err != 1)
462 ast_log(LOG_DEBUG, "Can't handle more than one device\n");
464 snd_pcm_poll_descriptors(handle, &pfd, err);
465 ast_log(LOG_DEBUG, "Acquired fd %d from the poll descriptor\n", pfd.fd);
467 if (stream == SND_PCM_STREAM_CAPTURE)
468 readdev = pfd.fd;
469 else
470 writedev = pfd.fd;
472 return handle;
475 static int soundcard_init(void)
477 alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE);
478 alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK);
480 if (!alsa.icard || !alsa.ocard) {
481 ast_log(LOG_ERROR, "Problem opening alsa I/O devices\n");
482 return -1;
485 return readdev;
488 static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration)
490 ast_mutex_lock(&alsalock);
491 ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
492 digit, duration);
493 ast_mutex_unlock(&alsalock);
494 return 0;
497 static int alsa_text(struct ast_channel *c, const char *text)
499 ast_mutex_lock(&alsalock);
500 ast_verbose(" << Console Received text %s >> \n", text);
501 ast_mutex_unlock(&alsalock);
502 return 0;
505 static void grab_owner(void)
507 while (alsa.owner && ast_mutex_trylock(&alsa.owner->lock)) {
508 ast_mutex_unlock(&alsalock);
509 usleep(1);
510 ast_mutex_lock(&alsalock);
514 static int alsa_call(struct ast_channel *c, char *dest, int timeout)
516 int res = 3;
517 struct ast_frame f = { AST_FRAME_CONTROL };
518 ast_mutex_lock(&alsalock);
519 ast_verbose(" << Call placed to '%s' on console >> \n", dest);
520 if (autoanswer) {
521 ast_verbose(" << Auto-answered >> \n");
522 grab_owner();
523 if (alsa.owner) {
524 f.subclass = AST_CONTROL_ANSWER;
525 ast_queue_frame(alsa.owner, &f);
526 ast_mutex_unlock(&alsa.owner->lock);
528 } else {
529 ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
530 grab_owner();
531 if (alsa.owner) {
532 f.subclass = AST_CONTROL_RINGING;
533 ast_queue_frame(alsa.owner, &f);
534 ast_mutex_unlock(&alsa.owner->lock);
536 write(sndcmd[1], &res, sizeof(res));
538 snd_pcm_prepare(alsa.icard);
539 snd_pcm_start(alsa.icard);
540 ast_mutex_unlock(&alsalock);
541 return 0;
544 static void answer_sound(void)
546 int res;
547 nosound = 1;
548 res = 4;
549 write(sndcmd[1], &res, sizeof(res));
553 static int alsa_answer(struct ast_channel *c)
555 ast_mutex_lock(&alsalock);
556 ast_verbose(" << Console call has been answered >> \n");
557 answer_sound();
558 ast_setstate(c, AST_STATE_UP);
559 cursound = -1;
560 snd_pcm_prepare(alsa.icard);
561 snd_pcm_start(alsa.icard);
562 ast_mutex_unlock(&alsalock);
563 return 0;
566 static int alsa_hangup(struct ast_channel *c)
568 int res;
569 ast_mutex_lock(&alsalock);
570 cursound = -1;
571 c->tech_pvt = NULL;
572 alsa.owner = NULL;
573 ast_verbose(" << Hangup on console >> \n");
574 ast_module_unref(ast_module_info->self);
575 if (hookstate) {
576 hookstate = 0;
577 if (!autoanswer) {
578 /* Congestion noise */
579 res = 2;
580 write(sndcmd[1], &res, sizeof(res));
583 snd_pcm_drop(alsa.icard);
584 ast_mutex_unlock(&alsalock);
585 return 0;
588 static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
590 static char sizbuf[8000];
591 static int sizpos = 0;
592 int len = sizpos;
593 int pos;
594 int res = 0;
595 /* size_t frames = 0; */
596 snd_pcm_state_t state;
598 /* Immediately return if no sound is enabled */
599 if (nosound)
600 return 0;
602 ast_mutex_lock(&alsalock);
603 /* Stop any currently playing sound */
604 if (cursound != -1) {
605 snd_pcm_drop(alsa.ocard);
606 snd_pcm_prepare(alsa.ocard);
607 cursound = -1;
611 /* We have to digest the frame in 160-byte portions */
612 if (f->datalen > sizeof(sizbuf) - sizpos) {
613 ast_log(LOG_WARNING, "Frame too large\n");
614 res = -1;
615 } else {
616 memcpy(sizbuf + sizpos, f->data, f->datalen);
617 len += f->datalen;
618 pos = 0;
619 #ifdef ALSA_MONITOR
620 alsa_monitor_write(sizbuf, len);
621 #endif
622 state = snd_pcm_state(alsa.ocard);
623 if (state == SND_PCM_STATE_XRUN)
624 snd_pcm_prepare(alsa.ocard);
625 res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
626 if (res == -EPIPE) {
627 #if DEBUG
628 ast_log(LOG_DEBUG, "XRUN write\n");
629 #endif
630 snd_pcm_prepare(alsa.ocard);
631 res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
632 if (res != len / 2) {
633 ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res));
634 res = -1;
635 } else if (res < 0) {
636 ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res));
637 res = -1;
639 } else {
640 if (res == -ESTRPIPE)
641 ast_log(LOG_ERROR, "You've got some big problems\n");
642 else if (res < 0)
643 ast_log(LOG_NOTICE, "Error %d on write\n", res);
646 ast_mutex_unlock(&alsalock);
647 if (res > 0)
648 res = 0;
649 return res;
653 static struct ast_frame *alsa_read(struct ast_channel *chan)
655 static struct ast_frame f;
656 static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET / 2];
657 short *buf;
658 static int readpos = 0;
659 static int left = FRAME_SIZE;
660 snd_pcm_state_t state;
661 int r = 0;
662 int off = 0;
664 ast_mutex_lock(&alsalock);
665 /* Acknowledge any pending cmd */
666 f.frametype = AST_FRAME_NULL;
667 f.subclass = 0;
668 f.samples = 0;
669 f.datalen = 0;
670 f.data = NULL;
671 f.offset = 0;
672 f.src = "Console";
673 f.mallocd = 0;
674 f.delivery.tv_sec = 0;
675 f.delivery.tv_usec = 0;
677 state = snd_pcm_state(alsa.icard);
678 if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) {
679 snd_pcm_prepare(alsa.icard);
682 buf = __buf + AST_FRIENDLY_OFFSET / 2;
684 r = snd_pcm_readi(alsa.icard, buf + readpos, left);
685 if (r == -EPIPE) {
686 #if DEBUG
687 ast_log(LOG_ERROR, "XRUN read\n");
688 #endif
689 snd_pcm_prepare(alsa.icard);
690 } else if (r == -ESTRPIPE) {
691 ast_log(LOG_ERROR, "-ESTRPIPE\n");
692 snd_pcm_prepare(alsa.icard);
693 } else if (r < 0) {
694 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
695 } else if (r >= 0) {
696 off -= r;
698 /* Update positions */
699 readpos += r;
700 left -= r;
702 if (readpos >= FRAME_SIZE) {
703 /* A real frame */
704 readpos = 0;
705 left = FRAME_SIZE;
706 if (chan->_state != AST_STATE_UP) {
707 /* Don't transmit unless it's up */
708 ast_mutex_unlock(&alsalock);
709 return &f;
711 f.frametype = AST_FRAME_VOICE;
712 f.subclass = AST_FORMAT_SLINEAR;
713 f.samples = FRAME_SIZE;
714 f.datalen = FRAME_SIZE * 2;
715 f.data = buf;
716 f.offset = AST_FRIENDLY_OFFSET;
717 f.src = "Console";
718 f.mallocd = 0;
719 #ifdef ALSA_MONITOR
720 alsa_monitor_read((char *) buf, FRAME_SIZE * 2);
721 #endif
724 ast_mutex_unlock(&alsalock);
725 return &f;
728 static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
730 struct chan_alsa_pvt *p = newchan->tech_pvt;
731 ast_mutex_lock(&alsalock);
732 p->owner = newchan;
733 ast_mutex_unlock(&alsalock);
734 return 0;
737 static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen)
739 int res = 0;
741 ast_mutex_lock(&alsalock);
743 switch (cond) {
744 case AST_CONTROL_BUSY:
745 res = 1;
746 break;
747 case AST_CONTROL_CONGESTION:
748 res = 2;
749 break;
750 case AST_CONTROL_RINGING:
751 break;
752 case -1:
753 res = -1;
754 break;
755 case AST_CONTROL_VIDUPDATE:
756 res = -1;
757 break;
758 case AST_CONTROL_HOLD:
759 ast_verbose(" << Console Has Been Placed on Hold >> \n");
760 ast_moh_start(chan, data, mohinterpret);
761 break;
762 case AST_CONTROL_UNHOLD:
763 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
764 ast_moh_stop(chan);
765 break;
766 default:
767 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
768 res = -1;
771 if (res > -1)
772 write(sndcmd[1], &res, sizeof(res));
774 ast_mutex_unlock(&alsalock);
776 return res;
779 static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
781 struct ast_channel *tmp = NULL;
783 if (!(tmp = ast_channel_alloc(1, state, 0, 0, "ALSA/%s", indevname)))
784 return NULL;
786 tmp->tech = &alsa_tech;
787 tmp->fds[0] = readdev;
788 tmp->nativeformats = AST_FORMAT_SLINEAR;
789 tmp->readformat = AST_FORMAT_SLINEAR;
790 tmp->writeformat = AST_FORMAT_SLINEAR;
791 tmp->tech_pvt = p;
792 if (!ast_strlen_zero(p->context))
793 ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
794 if (!ast_strlen_zero(p->exten))
795 ast_copy_string(tmp->exten, p->exten, sizeof(tmp->exten));
796 if (!ast_strlen_zero(language))
797 ast_string_field_set(tmp, language, language);
798 p->owner = tmp;
799 ast_module_ref(ast_module_info->self);
800 ast_jb_configure(tmp, &global_jbconf);
801 if (state != AST_STATE_DOWN) {
802 if (ast_pbx_start(tmp)) {
803 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
804 ast_hangup(tmp);
805 tmp = NULL;
809 return tmp;
812 static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause)
814 int oldformat = format;
815 struct ast_channel *tmp = NULL;
817 format &= AST_FORMAT_SLINEAR;
818 if (!format) {
819 ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat);
820 return NULL;
823 ast_mutex_lock(&alsalock);
825 if (alsa.owner) {
826 ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
827 *cause = AST_CAUSE_BUSY;
828 } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN)))
829 ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
831 ast_mutex_unlock(&alsalock);
833 return tmp;
836 static int console_autoanswer_deprecated(int fd, int argc, char *argv[])
838 int res = RESULT_SUCCESS;
840 if ((argc != 1) && (argc != 2))
841 return RESULT_SHOWUSAGE;
843 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;
856 ast_mutex_unlock(&alsalock);
858 return res;
861 static int console_autoanswer(int fd, int argc, char *argv[])
863 int res = RESULT_SUCCESS;;
864 if ((argc != 2) && (argc != 3))
865 return RESULT_SHOWUSAGE;
866 ast_mutex_lock(&alsalock);
867 if (argc == 2) {
868 ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
869 } else {
870 if (!strcasecmp(argv[2], "on"))
871 autoanswer = -1;
872 else if (!strcasecmp(argv[2], "off"))
873 autoanswer = 0;
874 else
875 res = RESULT_SHOWUSAGE;
877 ast_mutex_unlock(&alsalock);
878 return res;
881 static char *autoanswer_complete(const char *line, const char *word, int pos, int state)
883 #ifndef MIN
884 #define MIN(a,b) ((a) < (b) ? (a) : (b))
885 #endif
886 switch (state) {
887 case 0:
888 if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
889 return ast_strdup("on");
890 case 1:
891 if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
892 return ast_strdup("off");
893 default:
894 return NULL;
896 return NULL;
899 static const char autoanswer_usage[] =
900 "Usage: console autoanswer [on|off]\n"
901 " Enables or disables autoanswer feature. If used without\n"
902 " argument, displays the current on/off status of autoanswer.\n"
903 " The default value of autoanswer is in 'alsa.conf'.\n";
905 static int console_answer_deprecated(int fd, int argc, char *argv[])
907 int res = RESULT_SUCCESS;
909 if (argc != 1)
910 return RESULT_SHOWUSAGE;
912 ast_mutex_lock(&alsalock);
914 if (!alsa.owner) {
915 ast_cli(fd, "No one is calling us\n");
916 res = RESULT_FAILURE;
917 } else {
918 hookstate = 1;
919 cursound = -1;
920 grab_owner();
921 if (alsa.owner) {
922 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
923 ast_queue_frame(alsa.owner, &f);
924 ast_mutex_unlock(&alsa.owner->lock);
926 answer_sound();
929 snd_pcm_prepare(alsa.icard);
930 snd_pcm_start(alsa.icard);
932 ast_mutex_unlock(&alsalock);
934 return RESULT_SUCCESS;
937 static int console_answer(int fd, int argc, char *argv[])
939 int res = RESULT_SUCCESS;
941 if (argc != 2)
942 return RESULT_SHOWUSAGE;
944 ast_mutex_lock(&alsalock);
946 if (!alsa.owner) {
947 ast_cli(fd, "No one is calling us\n");
948 res = RESULT_FAILURE;
949 } else {
950 hookstate = 1;
951 cursound = -1;
952 grab_owner();
953 if (alsa.owner) {
954 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
955 ast_queue_frame(alsa.owner, &f);
956 ast_mutex_unlock(&alsa.owner->lock);
958 answer_sound();
961 snd_pcm_prepare(alsa.icard);
962 snd_pcm_start(alsa.icard);
964 ast_mutex_unlock(&alsalock);
966 return RESULT_SUCCESS;
969 static char sendtext_usage[] =
970 "Usage: console send text <message>\n"
971 " Sends a text message for display on the remote terminal.\n";
973 static int console_sendtext_deprecated(int fd, int argc, char *argv[])
975 int tmparg = 2;
976 int res = RESULT_SUCCESS;
978 if (argc < 2)
979 return RESULT_SHOWUSAGE;
981 ast_mutex_lock(&alsalock);
983 if (!alsa.owner) {
984 ast_cli(fd, "No one is calling us\n");
985 res = RESULT_FAILURE;
986 } else {
987 struct ast_frame f = { AST_FRAME_TEXT, 0 };
988 char text2send[256] = "";
989 text2send[0] = '\0';
990 while (tmparg < argc) {
991 strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
992 strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
994 text2send[strlen(text2send) - 1] = '\n';
995 f.data = text2send;
996 f.datalen = strlen(text2send) + 1;
997 grab_owner();
998 if (alsa.owner) {
999 ast_queue_frame(alsa.owner, &f);
1000 f.frametype = AST_FRAME_CONTROL;
1001 f.subclass = AST_CONTROL_ANSWER;
1002 f.data = NULL;
1003 f.datalen = 0;
1004 ast_queue_frame(alsa.owner, &f);
1005 ast_mutex_unlock(&alsa.owner->lock);
1009 ast_mutex_unlock(&alsalock);
1011 return res;
1014 static int console_sendtext(int fd, int argc, char *argv[])
1016 int tmparg = 3;
1017 int res = RESULT_SUCCESS;
1019 if (argc < 3)
1020 return RESULT_SHOWUSAGE;
1022 ast_mutex_lock(&alsalock);
1024 if (!alsa.owner) {
1025 ast_cli(fd, "No one is calling us\n");
1026 res = RESULT_FAILURE;
1027 } else {
1028 struct ast_frame f = { AST_FRAME_TEXT, 0 };
1029 char text2send[256] = "";
1030 text2send[0] = '\0';
1031 while (tmparg < argc) {
1032 strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
1033 strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
1035 text2send[strlen(text2send) - 1] = '\n';
1036 f.data = text2send;
1037 f.datalen = strlen(text2send) + 1;
1038 grab_owner();
1039 if (alsa.owner) {
1040 ast_queue_frame(alsa.owner, &f);
1041 f.frametype = AST_FRAME_CONTROL;
1042 f.subclass = AST_CONTROL_ANSWER;
1043 f.data = NULL;
1044 f.datalen = 0;
1045 ast_queue_frame(alsa.owner, &f);
1046 ast_mutex_unlock(&alsa.owner->lock);
1050 ast_mutex_unlock(&alsalock);
1052 return res;
1055 static char answer_usage[] =
1056 "Usage: console answer\n"
1057 " Answers an incoming call on the console (ALSA) channel.\n";
1059 static int console_hangup_deprecated(int fd, int argc, char *argv[])
1061 int res = RESULT_SUCCESS;
1063 if (argc != 1)
1064 return RESULT_SHOWUSAGE;
1066 cursound = -1;
1068 ast_mutex_lock(&alsalock);
1070 if (!alsa.owner && !hookstate) {
1071 ast_cli(fd, "No call to hangup up\n");
1072 res = RESULT_FAILURE;
1073 } else {
1074 hookstate = 0;
1075 grab_owner();
1076 if (alsa.owner) {
1077 ast_queue_hangup(alsa.owner);
1078 ast_mutex_unlock(&alsa.owner->lock);
1082 ast_mutex_unlock(&alsalock);
1084 return res;
1087 static int console_hangup(int fd, int argc, char *argv[])
1089 int res = RESULT_SUCCESS;
1091 if (argc != 2)
1092 return RESULT_SHOWUSAGE;
1094 cursound = -1;
1096 ast_mutex_lock(&alsalock);
1098 if (!alsa.owner && !hookstate) {
1099 ast_cli(fd, "No call to hangup up\n");
1100 res = RESULT_FAILURE;
1101 } else {
1102 hookstate = 0;
1103 grab_owner();
1104 if (alsa.owner) {
1105 ast_queue_hangup(alsa.owner);
1106 ast_mutex_unlock(&alsa.owner->lock);
1110 ast_mutex_unlock(&alsalock);
1112 return res;
1115 static char hangup_usage[] =
1116 "Usage: console hangup\n"
1117 " Hangs up any call currently placed on the console.\n";
1119 static int console_dial_deprecated(int fd, int argc, char *argv[])
1121 char tmp[256], *tmp2;
1122 char *mye, *myc;
1123 char *d;
1124 int res = RESULT_SUCCESS;
1126 if ((argc != 1) && (argc != 2))
1127 return RESULT_SHOWUSAGE;
1129 ast_mutex_lock(&alsalock);
1131 if (alsa.owner) {
1132 if (argc == 2) {
1133 d = argv[1];
1134 grab_owner();
1135 if (alsa.owner) {
1136 struct ast_frame f = { AST_FRAME_DTMF };
1137 while (*d) {
1138 f.subclass = *d;
1139 ast_queue_frame(alsa.owner, &f);
1140 d++;
1142 ast_mutex_unlock(&alsa.owner->lock);
1144 } else {
1145 ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
1146 res = RESULT_FAILURE;
1148 } else {
1149 mye = exten;
1150 myc = context;
1151 if (argc == 2) {
1152 char *stringp = NULL;
1153 ast_copy_string(tmp, argv[1], sizeof(tmp));
1154 stringp = tmp;
1155 strsep(&stringp, "@");
1156 tmp2 = strsep(&stringp, "@");
1157 if (!ast_strlen_zero(tmp))
1158 mye = tmp;
1159 if (!ast_strlen_zero(tmp2))
1160 myc = tmp2;
1162 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
1163 ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
1164 ast_copy_string(alsa.context, myc, sizeof(alsa.context));
1165 hookstate = 1;
1166 alsa_new(&alsa, AST_STATE_RINGING);
1167 } else
1168 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
1171 ast_mutex_unlock(&alsalock);
1173 return res;
1176 static int console_dial(int fd, int argc, char *argv[])
1178 char tmp[256], *tmp2;
1179 char *mye, *myc;
1180 char *d;
1181 int res = RESULT_SUCCESS;
1183 if ((argc != 2) && (argc != 3))
1184 return RESULT_SHOWUSAGE;
1186 ast_mutex_lock(&alsalock);
1188 if (alsa.owner) {
1189 if (argc == 3) {
1190 d = argv[2];
1191 grab_owner();
1192 if (alsa.owner) {
1193 struct ast_frame f = { AST_FRAME_DTMF };
1194 while (*d) {
1195 f.subclass = *d;
1196 ast_queue_frame(alsa.owner, &f);
1197 d++;
1199 ast_mutex_unlock(&alsa.owner->lock);
1201 } else {
1202 ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
1203 res = RESULT_FAILURE;
1205 } else {
1206 mye = exten;
1207 myc = context;
1208 if (argc == 3) {
1209 char *stringp = NULL;
1210 ast_copy_string(tmp, argv[2], sizeof(tmp));
1211 stringp = tmp;
1212 strsep(&stringp, "@");
1213 tmp2 = strsep(&stringp, "@");
1214 if (!ast_strlen_zero(tmp))
1215 mye = tmp;
1216 if (!ast_strlen_zero(tmp2))
1217 myc = tmp2;
1219 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
1220 ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
1221 ast_copy_string(alsa.context, myc, sizeof(alsa.context));
1222 hookstate = 1;
1223 alsa_new(&alsa, AST_STATE_RINGING);
1224 } else
1225 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
1228 ast_mutex_unlock(&alsalock);
1230 return res;
1233 static char dial_usage[] =
1234 "Usage: console dial [extension[@context]]\n"
1235 " Dials a given extension (and context if specified)\n";
1237 static struct ast_cli_entry cli_alsa_answer_deprecated = {
1238 { "answer", NULL },
1239 console_answer_deprecated, NULL,
1240 NULL };
1242 static struct ast_cli_entry cli_alsa_hangup_deprecated = {
1243 { "hangup", NULL },
1244 console_hangup_deprecated, NULL,
1245 NULL };
1247 static struct ast_cli_entry cli_alsa_dial_deprecated = {
1248 { "dial", NULL },
1249 console_dial_deprecated, NULL,
1250 NULL };
1252 static struct ast_cli_entry cli_alsa_send_text_deprecated = {
1253 { "send", "text", NULL },
1254 console_sendtext_deprecated, NULL,
1255 NULL };
1257 static struct ast_cli_entry cli_alsa_autoanswer_deprecated = {
1258 { "autoanswer", NULL },
1259 console_autoanswer_deprecated, NULL,
1260 NULL, autoanswer_complete };
1262 static struct ast_cli_entry cli_alsa[] = {
1263 { { "console", "answer", NULL },
1264 console_answer, "Answer an incoming console call",
1265 answer_usage, NULL, &cli_alsa_answer_deprecated },
1267 { { "console", "hangup", NULL },
1268 console_hangup, "Hangup a call on the console",
1269 hangup_usage, NULL, &cli_alsa_hangup_deprecated },
1271 { { "console", "dial", NULL },
1272 console_dial, "Dial an extension on the console",
1273 dial_usage, NULL, &cli_alsa_dial_deprecated },
1275 { { "console", "send", "text", NULL },
1276 console_sendtext, "Send text to the remote device",
1277 sendtext_usage, NULL, &cli_alsa_send_text_deprecated },
1279 { { "console", "autoanswer", NULL },
1280 console_autoanswer, "Sets/displays autoanswer",
1281 autoanswer_usage, autoanswer_complete, &cli_alsa_autoanswer_deprecated },
1284 static int load_module(void)
1286 int res;
1287 struct ast_config *cfg;
1288 struct ast_variable *v;
1290 /* Copy the default jb config over global_jbconf */
1291 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
1293 strcpy(mohinterpret, "default");
1295 if ((cfg = ast_config_load(config))) {
1296 v = ast_variable_browse(cfg, "general");
1297 for (; v; v = v->next) {
1298 /* handle jb conf */
1299 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
1300 continue;
1302 if (!strcasecmp(v->name, "autoanswer"))
1303 autoanswer = ast_true(v->value);
1304 else if (!strcasecmp(v->name, "silencesuppression"))
1305 silencesuppression = ast_true(v->value);
1306 else if (!strcasecmp(v->name, "silencethreshold"))
1307 silencethreshold = atoi(v->value);
1308 else if (!strcasecmp(v->name, "context"))
1309 ast_copy_string(context, v->value, sizeof(context));
1310 else if (!strcasecmp(v->name, "language"))
1311 ast_copy_string(language, v->value, sizeof(language));
1312 else if (!strcasecmp(v->name, "extension"))
1313 ast_copy_string(exten, v->value, sizeof(exten));
1314 else if (!strcasecmp(v->name, "input_device"))
1315 ast_copy_string(indevname, v->value, sizeof(indevname));
1316 else if (!strcasecmp(v->name, "output_device"))
1317 ast_copy_string(outdevname, v->value, sizeof(outdevname));
1318 else if (!strcasecmp(v->name, "mohinterpret"))
1319 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
1321 ast_config_destroy(cfg);
1323 res = pipe(sndcmd);
1324 if (res) {
1325 ast_log(LOG_ERROR, "Unable to create pipe\n");
1326 return -1;
1328 res = soundcard_init();
1329 if (res < 0) {
1330 if (option_verbose > 1) {
1331 ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
1332 ast_verbose(VERBOSE_PREFIX_2 "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
1334 return 0;
1337 res = ast_channel_register(&alsa_tech);
1338 if (res < 0) {
1339 ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
1340 return -1;
1342 ast_cli_register_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
1344 ast_pthread_create_background(&sthread, NULL, sound_thread, NULL);
1345 #ifdef ALSA_MONITOR
1346 if (alsa_monitor_start())
1347 ast_log(LOG_ERROR, "Problem starting Monitoring\n");
1348 #endif
1349 return 0;
1352 static int unload_module(void)
1354 ast_channel_unregister(&alsa_tech);
1355 ast_cli_unregister_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
1357 if (alsa.icard)
1358 snd_pcm_close(alsa.icard);
1359 if (alsa.ocard)
1360 snd_pcm_close(alsa.ocard);
1361 if (sndcmd[0] > 0) {
1362 close(sndcmd[0]);
1363 close(sndcmd[1]);
1365 if (alsa.owner)
1366 ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
1367 if (alsa.owner)
1368 return -1;
1369 return 0;
1372 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ALSA Console Channel Driver");