avoid the weird usage of assert() in the ALSA header files that gcc 4.2 wants to...
[asterisk-bristuff.git] / channels / chan_alsa.c
blob79bc313cd6f999ad213c6ed530152d34f5672fb6
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 hwparams = alloca(snd_pcm_hw_params_sizeof());
371 memset(hwparams, 0, snd_pcm_hw_params_sizeof());
372 snd_pcm_hw_params_any(handle, hwparams);
374 err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
375 if (err < 0)
376 ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err));
378 err = snd_pcm_hw_params_set_format(handle, hwparams, format);
379 if (err < 0)
380 ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err));
382 err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
383 if (err < 0)
384 ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err));
386 direction = 0;
387 err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction);
388 if (rate != DESIRED_RATE)
389 ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate);
391 direction = 0;
392 err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction);
393 if (err < 0)
394 ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err));
395 else
396 ast_log(LOG_DEBUG, "Period size is %d\n", err);
398 buffer_size = 4096 * 2; /* period_size * 16; */
399 err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
400 if (err < 0)
401 ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err));
402 else
403 ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err);
405 #if 0
406 direction = 0;
407 err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, &direction);
408 if (err < 0)
409 ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err));
411 err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0);
412 if (err < 0)
413 ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err));
414 #endif
416 err = snd_pcm_hw_params(handle, hwparams);
417 if (err < 0)
418 ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err));
420 swparams = alloca(snd_pcm_sw_params_sizeof());
421 memset(swparams, 0, snd_pcm_sw_params_sizeof());
422 snd_pcm_sw_params_current(handle, swparams);
424 #if 1
425 if (stream == SND_PCM_STREAM_PLAYBACK)
426 start_threshold = period_size;
427 else
428 start_threshold = 1;
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 #endif
435 #if 1
436 if (stream == SND_PCM_STREAM_PLAYBACK)
437 stop_threshold = buffer_size;
438 else
439 stop_threshold = buffer_size;
441 err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
442 if (err < 0)
443 ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err));
444 #endif
445 #if 0
446 err = snd_pcm_sw_params_set_xfer_align(handle, swparams, PERIOD_FRAMES);
447 if (err < 0)
448 ast_log(LOG_ERROR, "Unable to set xfer alignment: %s\n", snd_strerror(err));
449 #endif
451 #if 0
452 err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, silencethreshold);
453 if (err < 0)
454 ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err));
455 #endif
456 err = snd_pcm_sw_params(handle, swparams);
457 if (err < 0)
458 ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err));
460 err = snd_pcm_poll_descriptors_count(handle);
461 if (err <= 0)
462 ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err));
463 if (err != 1)
464 ast_log(LOG_DEBUG, "Can't handle more than one device\n");
466 snd_pcm_poll_descriptors(handle, &pfd, err);
467 ast_log(LOG_DEBUG, "Acquired fd %d from the poll descriptor\n", pfd.fd);
469 if (stream == SND_PCM_STREAM_CAPTURE)
470 readdev = pfd.fd;
471 else
472 writedev = pfd.fd;
474 return handle;
477 static int soundcard_init(void)
479 alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE);
480 alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK);
482 if (!alsa.icard || !alsa.ocard) {
483 ast_log(LOG_ERROR, "Problem opening alsa I/O devices\n");
484 return -1;
487 return readdev;
490 static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration)
492 ast_mutex_lock(&alsalock);
493 ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
494 digit, duration);
495 ast_mutex_unlock(&alsalock);
496 return 0;
499 static int alsa_text(struct ast_channel *c, const char *text)
501 ast_mutex_lock(&alsalock);
502 ast_verbose(" << Console Received text %s >> \n", text);
503 ast_mutex_unlock(&alsalock);
504 return 0;
507 static void grab_owner(void)
509 while (alsa.owner && ast_mutex_trylock(&alsa.owner->lock)) {
510 ast_mutex_unlock(&alsalock);
511 usleep(1);
512 ast_mutex_lock(&alsalock);
516 static int alsa_call(struct ast_channel *c, char *dest, int timeout)
518 int res = 3;
519 struct ast_frame f = { AST_FRAME_CONTROL };
520 ast_mutex_lock(&alsalock);
521 ast_verbose(" << Call placed to '%s' on console >> \n", dest);
522 if (autoanswer) {
523 ast_verbose(" << Auto-answered >> \n");
524 grab_owner();
525 if (alsa.owner) {
526 f.subclass = AST_CONTROL_ANSWER;
527 ast_queue_frame(alsa.owner, &f);
528 ast_mutex_unlock(&alsa.owner->lock);
530 } else {
531 ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
532 grab_owner();
533 if (alsa.owner) {
534 f.subclass = AST_CONTROL_RINGING;
535 ast_queue_frame(alsa.owner, &f);
536 ast_mutex_unlock(&alsa.owner->lock);
538 write(sndcmd[1], &res, sizeof(res));
540 snd_pcm_prepare(alsa.icard);
541 snd_pcm_start(alsa.icard);
542 ast_mutex_unlock(&alsalock);
543 return 0;
546 static void answer_sound(void)
548 int res;
549 nosound = 1;
550 res = 4;
551 write(sndcmd[1], &res, sizeof(res));
555 static int alsa_answer(struct ast_channel *c)
557 ast_mutex_lock(&alsalock);
558 ast_verbose(" << Console call has been answered >> \n");
559 answer_sound();
560 ast_setstate(c, AST_STATE_UP);
561 cursound = -1;
562 snd_pcm_prepare(alsa.icard);
563 snd_pcm_start(alsa.icard);
564 ast_mutex_unlock(&alsalock);
565 return 0;
568 static int alsa_hangup(struct ast_channel *c)
570 int res;
571 ast_mutex_lock(&alsalock);
572 cursound = -1;
573 c->tech_pvt = NULL;
574 alsa.owner = NULL;
575 ast_verbose(" << Hangup on console >> \n");
576 ast_module_unref(ast_module_info->self);
577 if (hookstate) {
578 hookstate = 0;
579 if (!autoanswer) {
580 /* Congestion noise */
581 res = 2;
582 write(sndcmd[1], &res, sizeof(res));
585 snd_pcm_drop(alsa.icard);
586 ast_mutex_unlock(&alsalock);
587 return 0;
590 static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
592 static char sizbuf[8000];
593 static int sizpos = 0;
594 int len = sizpos;
595 int pos;
596 int res = 0;
597 /* size_t frames = 0; */
598 snd_pcm_state_t state;
600 /* Immediately return if no sound is enabled */
601 if (nosound)
602 return 0;
604 ast_mutex_lock(&alsalock);
605 /* Stop any currently playing sound */
606 if (cursound != -1) {
607 snd_pcm_drop(alsa.ocard);
608 snd_pcm_prepare(alsa.ocard);
609 cursound = -1;
613 /* We have to digest the frame in 160-byte portions */
614 if (f->datalen > sizeof(sizbuf) - sizpos) {
615 ast_log(LOG_WARNING, "Frame too large\n");
616 res = -1;
617 } else {
618 memcpy(sizbuf + sizpos, f->data, f->datalen);
619 len += f->datalen;
620 pos = 0;
621 #ifdef ALSA_MONITOR
622 alsa_monitor_write(sizbuf, len);
623 #endif
624 state = snd_pcm_state(alsa.ocard);
625 if (state == SND_PCM_STATE_XRUN)
626 snd_pcm_prepare(alsa.ocard);
627 res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
628 if (res == -EPIPE) {
629 #if DEBUG
630 ast_log(LOG_DEBUG, "XRUN write\n");
631 #endif
632 snd_pcm_prepare(alsa.ocard);
633 res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
634 if (res != len / 2) {
635 ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res));
636 res = -1;
637 } else if (res < 0) {
638 ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res));
639 res = -1;
641 } else {
642 if (res == -ESTRPIPE)
643 ast_log(LOG_ERROR, "You've got some big problems\n");
644 else if (res < 0)
645 ast_log(LOG_NOTICE, "Error %d on write\n", res);
648 ast_mutex_unlock(&alsalock);
649 if (res > 0)
650 res = 0;
651 return res;
655 static struct ast_frame *alsa_read(struct ast_channel *chan)
657 static struct ast_frame f;
658 static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET / 2];
659 short *buf;
660 static int readpos = 0;
661 static int left = FRAME_SIZE;
662 snd_pcm_state_t state;
663 int r = 0;
664 int off = 0;
666 ast_mutex_lock(&alsalock);
667 /* Acknowledge any pending cmd */
668 f.frametype = AST_FRAME_NULL;
669 f.subclass = 0;
670 f.samples = 0;
671 f.datalen = 0;
672 f.data = NULL;
673 f.offset = 0;
674 f.src = "Console";
675 f.mallocd = 0;
676 f.delivery.tv_sec = 0;
677 f.delivery.tv_usec = 0;
679 state = snd_pcm_state(alsa.icard);
680 if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) {
681 snd_pcm_prepare(alsa.icard);
684 buf = __buf + AST_FRIENDLY_OFFSET / 2;
686 r = snd_pcm_readi(alsa.icard, buf + readpos, left);
687 if (r == -EPIPE) {
688 #if DEBUG
689 ast_log(LOG_ERROR, "XRUN read\n");
690 #endif
691 snd_pcm_prepare(alsa.icard);
692 } else if (r == -ESTRPIPE) {
693 ast_log(LOG_ERROR, "-ESTRPIPE\n");
694 snd_pcm_prepare(alsa.icard);
695 } else if (r < 0) {
696 ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
697 } else if (r >= 0) {
698 off -= r;
700 /* Update positions */
701 readpos += r;
702 left -= r;
704 if (readpos >= FRAME_SIZE) {
705 /* A real frame */
706 readpos = 0;
707 left = FRAME_SIZE;
708 if (chan->_state != AST_STATE_UP) {
709 /* Don't transmit unless it's up */
710 ast_mutex_unlock(&alsalock);
711 return &f;
713 f.frametype = AST_FRAME_VOICE;
714 f.subclass = AST_FORMAT_SLINEAR;
715 f.samples = FRAME_SIZE;
716 f.datalen = FRAME_SIZE * 2;
717 f.data = buf;
718 f.offset = AST_FRIENDLY_OFFSET;
719 f.src = "Console";
720 f.mallocd = 0;
721 #ifdef ALSA_MONITOR
722 alsa_monitor_read((char *) buf, FRAME_SIZE * 2);
723 #endif
726 ast_mutex_unlock(&alsalock);
727 return &f;
730 static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
732 struct chan_alsa_pvt *p = newchan->tech_pvt;
733 ast_mutex_lock(&alsalock);
734 p->owner = newchan;
735 ast_mutex_unlock(&alsalock);
736 return 0;
739 static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen)
741 int res = 0;
743 ast_mutex_lock(&alsalock);
745 switch (cond) {
746 case AST_CONTROL_BUSY:
747 res = 1;
748 break;
749 case AST_CONTROL_CONGESTION:
750 res = 2;
751 break;
752 case AST_CONTROL_RINGING:
753 case AST_CONTROL_PROGRESS:
754 break;
755 case -1:
756 res = -1;
757 break;
758 case AST_CONTROL_VIDUPDATE:
759 res = -1;
760 break;
761 case AST_CONTROL_HOLD:
762 ast_verbose(" << Console Has Been Placed on Hold >> \n");
763 ast_moh_start(chan, data, mohinterpret);
764 break;
765 case AST_CONTROL_UNHOLD:
766 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
767 ast_moh_stop(chan);
768 break;
769 default:
770 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
771 res = -1;
774 if (res > -1)
775 write(sndcmd[1], &res, sizeof(res));
777 ast_mutex_unlock(&alsalock);
779 return res;
782 static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
784 struct ast_channel *tmp = NULL;
786 if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, "ALSA/%s", indevname)))
787 return NULL;
789 tmp->tech = &alsa_tech;
790 tmp->fds[0] = readdev;
791 tmp->nativeformats = AST_FORMAT_SLINEAR;
792 tmp->readformat = AST_FORMAT_SLINEAR;
793 tmp->writeformat = AST_FORMAT_SLINEAR;
794 tmp->tech_pvt = p;
795 if (!ast_strlen_zero(p->context))
796 ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
797 if (!ast_strlen_zero(p->exten))
798 ast_copy_string(tmp->exten, p->exten, sizeof(tmp->exten));
799 if (!ast_strlen_zero(language))
800 ast_string_field_set(tmp, language, language);
801 p->owner = tmp;
802 ast_module_ref(ast_module_info->self);
803 ast_jb_configure(tmp, &global_jbconf);
804 if (state != AST_STATE_DOWN) {
805 if (ast_pbx_start(tmp)) {
806 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
807 ast_hangup(tmp);
808 tmp = NULL;
812 return tmp;
815 static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause)
817 int oldformat = format;
818 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;
826 ast_mutex_lock(&alsalock);
828 if (alsa.owner) {
829 ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
830 *cause = AST_CAUSE_BUSY;
831 } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN)))
832 ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
834 ast_mutex_unlock(&alsalock);
836 return tmp;
839 static int console_autoanswer_deprecated(int fd, int argc, char *argv[])
841 int res = RESULT_SUCCESS;
843 if ((argc != 1) && (argc != 2))
844 return RESULT_SHOWUSAGE;
846 ast_mutex_lock(&alsalock);
848 if (argc == 1) {
849 ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
850 } else {
851 if (!strcasecmp(argv[1], "on"))
852 autoanswer = -1;
853 else if (!strcasecmp(argv[1], "off"))
854 autoanswer = 0;
855 else
856 res = RESULT_SHOWUSAGE;
859 ast_mutex_unlock(&alsalock);
861 return res;
864 static int console_autoanswer(int fd, int argc, char *argv[])
866 int res = RESULT_SUCCESS;;
867 if ((argc != 2) && (argc != 3))
868 return RESULT_SHOWUSAGE;
869 ast_mutex_lock(&alsalock);
870 if (argc == 2) {
871 ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
872 } else {
873 if (!strcasecmp(argv[2], "on"))
874 autoanswer = -1;
875 else if (!strcasecmp(argv[2], "off"))
876 autoanswer = 0;
877 else
878 res = RESULT_SHOWUSAGE;
880 ast_mutex_unlock(&alsalock);
881 return res;
884 static char *autoanswer_complete(const char *line, const char *word, int pos, int state)
886 #ifndef MIN
887 #define MIN(a,b) ((a) < (b) ? (a) : (b))
888 #endif
889 switch (state) {
890 case 0:
891 if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
892 return ast_strdup("on");
893 case 1:
894 if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
895 return ast_strdup("off");
896 default:
897 return NULL;
899 return NULL;
902 static const char autoanswer_usage[] =
903 "Usage: console autoanswer [on|off]\n"
904 " Enables or disables autoanswer feature. If used without\n"
905 " argument, displays the current on/off status of autoanswer.\n"
906 " The default value of autoanswer is in 'alsa.conf'.\n";
908 static int console_answer_deprecated(int fd, int argc, char *argv[])
910 int res = RESULT_SUCCESS;
912 if (argc != 1)
913 return RESULT_SHOWUSAGE;
915 ast_mutex_lock(&alsalock);
917 if (!alsa.owner) {
918 ast_cli(fd, "No one is calling us\n");
919 res = RESULT_FAILURE;
920 } else {
921 hookstate = 1;
922 cursound = -1;
923 grab_owner();
924 if (alsa.owner) {
925 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
926 ast_queue_frame(alsa.owner, &f);
927 ast_mutex_unlock(&alsa.owner->lock);
929 answer_sound();
932 snd_pcm_prepare(alsa.icard);
933 snd_pcm_start(alsa.icard);
935 ast_mutex_unlock(&alsalock);
937 return RESULT_SUCCESS;
940 static int console_answer(int fd, int argc, char *argv[])
942 int res = RESULT_SUCCESS;
944 if (argc != 2)
945 return RESULT_SHOWUSAGE;
947 ast_mutex_lock(&alsalock);
949 if (!alsa.owner) {
950 ast_cli(fd, "No one is calling us\n");
951 res = RESULT_FAILURE;
952 } else {
953 hookstate = 1;
954 cursound = -1;
955 grab_owner();
956 if (alsa.owner) {
957 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
958 ast_queue_frame(alsa.owner, &f);
959 ast_mutex_unlock(&alsa.owner->lock);
961 answer_sound();
964 snd_pcm_prepare(alsa.icard);
965 snd_pcm_start(alsa.icard);
967 ast_mutex_unlock(&alsalock);
969 return RESULT_SUCCESS;
972 static char sendtext_usage[] =
973 "Usage: console send text <message>\n"
974 " Sends a text message for display on the remote terminal.\n";
976 static int console_sendtext_deprecated(int fd, int argc, char *argv[])
978 int tmparg = 2;
979 int res = RESULT_SUCCESS;
981 if (argc < 2)
982 return RESULT_SHOWUSAGE;
984 ast_mutex_lock(&alsalock);
986 if (!alsa.owner) {
987 ast_cli(fd, "No one is calling us\n");
988 res = RESULT_FAILURE;
989 } else {
990 struct ast_frame f = { AST_FRAME_TEXT, 0 };
991 char text2send[256] = "";
992 text2send[0] = '\0';
993 while (tmparg < argc) {
994 strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
995 strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
997 text2send[strlen(text2send) - 1] = '\n';
998 f.data = text2send;
999 f.datalen = strlen(text2send) + 1;
1000 grab_owner();
1001 if (alsa.owner) {
1002 ast_queue_frame(alsa.owner, &f);
1003 f.frametype = AST_FRAME_CONTROL;
1004 f.subclass = AST_CONTROL_ANSWER;
1005 f.data = NULL;
1006 f.datalen = 0;
1007 ast_queue_frame(alsa.owner, &f);
1008 ast_mutex_unlock(&alsa.owner->lock);
1012 ast_mutex_unlock(&alsalock);
1014 return res;
1017 static int console_sendtext(int fd, int argc, char *argv[])
1019 int tmparg = 3;
1020 int res = RESULT_SUCCESS;
1022 if (argc < 3)
1023 return RESULT_SHOWUSAGE;
1025 ast_mutex_lock(&alsalock);
1027 if (!alsa.owner) {
1028 ast_cli(fd, "No one is calling us\n");
1029 res = RESULT_FAILURE;
1030 } else {
1031 struct ast_frame f = { AST_FRAME_TEXT, 0 };
1032 char text2send[256] = "";
1033 text2send[0] = '\0';
1034 while (tmparg < argc) {
1035 strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
1036 strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
1038 text2send[strlen(text2send) - 1] = '\n';
1039 f.data = text2send;
1040 f.datalen = strlen(text2send) + 1;
1041 grab_owner();
1042 if (alsa.owner) {
1043 ast_queue_frame(alsa.owner, &f);
1044 f.frametype = AST_FRAME_CONTROL;
1045 f.subclass = AST_CONTROL_ANSWER;
1046 f.data = NULL;
1047 f.datalen = 0;
1048 ast_queue_frame(alsa.owner, &f);
1049 ast_mutex_unlock(&alsa.owner->lock);
1053 ast_mutex_unlock(&alsalock);
1055 return res;
1058 static char answer_usage[] =
1059 "Usage: console answer\n"
1060 " Answers an incoming call on the console (ALSA) channel.\n";
1062 static int console_hangup_deprecated(int fd, int argc, char *argv[])
1064 int res = RESULT_SUCCESS;
1066 if (argc != 1)
1067 return RESULT_SHOWUSAGE;
1069 cursound = -1;
1071 ast_mutex_lock(&alsalock);
1073 if (!alsa.owner && !hookstate) {
1074 ast_cli(fd, "No call to hangup up\n");
1075 res = RESULT_FAILURE;
1076 } else {
1077 hookstate = 0;
1078 grab_owner();
1079 if (alsa.owner) {
1080 ast_queue_hangup(alsa.owner);
1081 ast_mutex_unlock(&alsa.owner->lock);
1085 ast_mutex_unlock(&alsalock);
1087 return res;
1090 static int console_hangup(int fd, int argc, char *argv[])
1092 int res = RESULT_SUCCESS;
1094 if (argc != 2)
1095 return RESULT_SHOWUSAGE;
1097 cursound = -1;
1099 ast_mutex_lock(&alsalock);
1101 if (!alsa.owner && !hookstate) {
1102 ast_cli(fd, "No call to hangup up\n");
1103 res = RESULT_FAILURE;
1104 } else {
1105 hookstate = 0;
1106 grab_owner();
1107 if (alsa.owner) {
1108 ast_queue_hangup(alsa.owner);
1109 ast_mutex_unlock(&alsa.owner->lock);
1113 ast_mutex_unlock(&alsalock);
1115 return res;
1118 static char hangup_usage[] =
1119 "Usage: console hangup\n"
1120 " Hangs up any call currently placed on the console.\n";
1122 static int console_dial_deprecated(int fd, int argc, char *argv[])
1124 char tmp[256], *tmp2;
1125 char *mye, *myc;
1126 char *d;
1127 int res = RESULT_SUCCESS;
1129 if ((argc != 1) && (argc != 2))
1130 return RESULT_SHOWUSAGE;
1132 ast_mutex_lock(&alsalock);
1134 if (alsa.owner) {
1135 if (argc == 2) {
1136 d = argv[1];
1137 grab_owner();
1138 if (alsa.owner) {
1139 struct ast_frame f = { AST_FRAME_DTMF };
1140 while (*d) {
1141 f.subclass = *d;
1142 ast_queue_frame(alsa.owner, &f);
1143 d++;
1145 ast_mutex_unlock(&alsa.owner->lock);
1147 } else {
1148 ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
1149 res = RESULT_FAILURE;
1151 } else {
1152 mye = exten;
1153 myc = context;
1154 if (argc == 2) {
1155 char *stringp = NULL;
1156 ast_copy_string(tmp, argv[1], sizeof(tmp));
1157 stringp = tmp;
1158 strsep(&stringp, "@");
1159 tmp2 = strsep(&stringp, "@");
1160 if (!ast_strlen_zero(tmp))
1161 mye = tmp;
1162 if (!ast_strlen_zero(tmp2))
1163 myc = tmp2;
1165 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
1166 ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
1167 ast_copy_string(alsa.context, myc, sizeof(alsa.context));
1168 hookstate = 1;
1169 alsa_new(&alsa, AST_STATE_RINGING);
1170 } else
1171 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
1174 ast_mutex_unlock(&alsalock);
1176 return res;
1179 static int console_dial(int fd, int argc, char *argv[])
1181 char tmp[256], *tmp2;
1182 char *mye, *myc;
1183 char *d;
1184 int res = RESULT_SUCCESS;
1186 if ((argc != 2) && (argc != 3))
1187 return RESULT_SHOWUSAGE;
1189 ast_mutex_lock(&alsalock);
1191 if (alsa.owner) {
1192 if (argc == 3) {
1193 d = argv[2];
1194 grab_owner();
1195 if (alsa.owner) {
1196 struct ast_frame f = { AST_FRAME_DTMF };
1197 while (*d) {
1198 f.subclass = *d;
1199 ast_queue_frame(alsa.owner, &f);
1200 d++;
1202 ast_mutex_unlock(&alsa.owner->lock);
1204 } else {
1205 ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
1206 res = RESULT_FAILURE;
1208 } else {
1209 mye = exten;
1210 myc = context;
1211 if (argc == 3) {
1212 char *stringp = NULL;
1213 ast_copy_string(tmp, argv[2], sizeof(tmp));
1214 stringp = tmp;
1215 strsep(&stringp, "@");
1216 tmp2 = strsep(&stringp, "@");
1217 if (!ast_strlen_zero(tmp))
1218 mye = tmp;
1219 if (!ast_strlen_zero(tmp2))
1220 myc = tmp2;
1222 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
1223 ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
1224 ast_copy_string(alsa.context, myc, sizeof(alsa.context));
1225 hookstate = 1;
1226 alsa_new(&alsa, AST_STATE_RINGING);
1227 } else
1228 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
1231 ast_mutex_unlock(&alsalock);
1233 return res;
1236 static char dial_usage[] =
1237 "Usage: console dial [extension[@context]]\n"
1238 " Dials a given extension (and context if specified)\n";
1240 static struct ast_cli_entry cli_alsa_answer_deprecated = {
1241 { "answer", NULL },
1242 console_answer_deprecated, NULL,
1243 NULL };
1245 static struct ast_cli_entry cli_alsa_hangup_deprecated = {
1246 { "hangup", NULL },
1247 console_hangup_deprecated, NULL,
1248 NULL };
1250 static struct ast_cli_entry cli_alsa_dial_deprecated = {
1251 { "dial", NULL },
1252 console_dial_deprecated, NULL,
1253 NULL };
1255 static struct ast_cli_entry cli_alsa_send_text_deprecated = {
1256 { "send", "text", NULL },
1257 console_sendtext_deprecated, NULL,
1258 NULL };
1260 static struct ast_cli_entry cli_alsa_autoanswer_deprecated = {
1261 { "autoanswer", NULL },
1262 console_autoanswer_deprecated, NULL,
1263 NULL, autoanswer_complete };
1265 static struct ast_cli_entry cli_alsa[] = {
1266 { { "console", "answer", NULL },
1267 console_answer, "Answer an incoming console call",
1268 answer_usage, NULL, &cli_alsa_answer_deprecated },
1270 { { "console", "hangup", NULL },
1271 console_hangup, "Hangup a call on the console",
1272 hangup_usage, NULL, &cli_alsa_hangup_deprecated },
1274 { { "console", "dial", NULL },
1275 console_dial, "Dial an extension on the console",
1276 dial_usage, NULL, &cli_alsa_dial_deprecated },
1278 { { "console", "send", "text", NULL },
1279 console_sendtext, "Send text to the remote device",
1280 sendtext_usage, NULL, &cli_alsa_send_text_deprecated },
1282 { { "console", "autoanswer", NULL },
1283 console_autoanswer, "Sets/displays autoanswer",
1284 autoanswer_usage, autoanswer_complete, &cli_alsa_autoanswer_deprecated },
1287 static int load_module(void)
1289 int res;
1290 struct ast_config *cfg;
1291 struct ast_variable *v;
1293 /* Copy the default jb config over global_jbconf */
1294 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
1296 strcpy(mohinterpret, "default");
1298 if ((cfg = ast_config_load(config))) {
1299 v = ast_variable_browse(cfg, "general");
1300 for (; v; v = v->next) {
1301 /* handle jb conf */
1302 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
1303 continue;
1305 if (!strcasecmp(v->name, "autoanswer"))
1306 autoanswer = ast_true(v->value);
1307 else if (!strcasecmp(v->name, "silencesuppression"))
1308 silencesuppression = ast_true(v->value);
1309 else if (!strcasecmp(v->name, "silencethreshold"))
1310 silencethreshold = atoi(v->value);
1311 else if (!strcasecmp(v->name, "context"))
1312 ast_copy_string(context, v->value, sizeof(context));
1313 else if (!strcasecmp(v->name, "language"))
1314 ast_copy_string(language, v->value, sizeof(language));
1315 else if (!strcasecmp(v->name, "extension"))
1316 ast_copy_string(exten, v->value, sizeof(exten));
1317 else if (!strcasecmp(v->name, "input_device"))
1318 ast_copy_string(indevname, v->value, sizeof(indevname));
1319 else if (!strcasecmp(v->name, "output_device"))
1320 ast_copy_string(outdevname, v->value, sizeof(outdevname));
1321 else if (!strcasecmp(v->name, "mohinterpret"))
1322 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
1324 ast_config_destroy(cfg);
1326 res = pipe(sndcmd);
1327 if (res) {
1328 ast_log(LOG_ERROR, "Unable to create pipe\n");
1329 return -1;
1331 res = soundcard_init();
1332 if (res < 0) {
1333 if (option_verbose > 1) {
1334 ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
1335 ast_verbose(VERBOSE_PREFIX_2 "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
1337 return 0;
1340 res = ast_channel_register(&alsa_tech);
1341 if (res < 0) {
1342 ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
1343 return -1;
1345 ast_cli_register_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
1347 ast_pthread_create_background(&sthread, NULL, sound_thread, NULL);
1348 #ifdef ALSA_MONITOR
1349 if (alsa_monitor_start())
1350 ast_log(LOG_ERROR, "Problem starting Monitoring\n");
1351 #endif
1352 return 0;
1355 static int unload_module(void)
1357 ast_channel_unregister(&alsa_tech);
1358 ast_cli_unregister_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
1360 if (alsa.icard)
1361 snd_pcm_close(alsa.icard);
1362 if (alsa.ocard)
1363 snd_pcm_close(alsa.ocard);
1364 if (sndcmd[0] > 0) {
1365 close(sndcmd[0]);
1366 close(sndcmd[1]);
1368 if (alsa.owner)
1369 ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
1370 if (alsa.owner)
1371 return -1;
1372 return 0;
1375 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ALSA Console Channel Driver");