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.
20 * \brief ALSA sound card channel driver
22 * \author Matthew Fredrickson <creslin@digium.com>
27 * \ingroup channel_drivers
31 <depend>asound</depend>
36 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
41 #include <sys/ioctl.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"
72 #include "alsa-monitor.h"
75 /*! Global jitterbuffer configuration - by default, jb is disabled */
76 static struct ast_jb_conf default_jbconf
= {
79 .resync_threshold
= -1,
82 static struct ast_jb_conf global_jbconf
;
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
;
105 static snd_pcm_format_t format
= SND_PCM_FORMAT_S16_BE
;
108 static char indevname
[50] = ALSA_INDEV
;
109 static char outdevname
[50] = ALSA_OUTDEV
;
112 static struct timeval lasttime
;
115 static int silencesuppression
= 0;
116 static int silencethreshold
= 1000;
118 AST_MUTEX_DEFINE_STATIC(alsalock
);
120 static const char tdesc
[] = "ALSA Console Channel Driver";
121 static const char config
[] = "alsa.conf";
123 static char context
[AST_MAX_CONTEXT
] = "default";
124 static char language
[MAX_LANGUAGE
] = "";
125 static char exten
[AST_MAX_EXTENSION
] = "s";
126 static char mohinterpret
[MAX_MUSICCLASS
];
128 static int hookstate
= 0;
130 static short silence
[FRAME_SIZE
] = { 0, };
141 static struct sound sounds
[] = {
142 {AST_CONTROL_RINGING
, ringtone
, sizeof(ringtone
) / 2, 16000, 32000, 1},
143 {AST_CONTROL_BUSY
, busy
, sizeof(busy
) / 2, 4000, 4000, 1},
144 {AST_CONTROL_CONGESTION
, busy
, sizeof(busy
) / 2, 2000, 2000, 1},
145 {AST_CONTROL_RING
, ring10
, sizeof(ring10
) / 2, 16000, 32000, 1},
146 {AST_CONTROL_ANSWER
, answer
, sizeof(answer
) / 2, 2200, 0, 0},
149 /* Sound command pipe */
150 static int sndcmd
[2];
152 static struct chan_alsa_pvt
{
153 /* We only have one ALSA structure -- near sighted perhaps, but it
154 keeps this driver as simple as possible -- as it should be. */
155 struct ast_channel
*owner
;
156 char exten
[AST_MAX_EXTENSION
];
157 char context
[AST_MAX_CONTEXT
];
161 snd_pcm_t
*icard
, *ocard
;
165 /* Number of buffers... Each is FRAMESIZE/8 ms long. For example
166 with 160 sample frames, and a buffer size of 3, we have a 60ms buffer,
171 #define MAX_BUFFER_SIZE 100
173 /* File descriptors for sound device */
174 static int readdev
= -1;
175 static int writedev
= -1;
177 static int autoanswer
= 1;
179 static int cursound
= -1;
180 static int sampsent
= 0;
181 static int silencelen
= 0;
182 static int offset
= 0;
183 static int nosound
= 0;
186 static struct ast_channel
*alsa_request(const char *type
, int format
, void *data
, int *cause
);
187 static int alsa_digit(struct ast_channel
*c
, char digit
, unsigned int duration
);
188 static int alsa_text(struct ast_channel
*c
, const char *text
);
189 static int alsa_hangup(struct ast_channel
*c
);
190 static int alsa_answer(struct ast_channel
*c
);
191 static struct ast_frame
*alsa_read(struct ast_channel
*chan
);
192 static int alsa_call(struct ast_channel
*c
, char *dest
, int timeout
);
193 static int alsa_write(struct ast_channel
*chan
, struct ast_frame
*f
);
194 static int alsa_indicate(struct ast_channel
*chan
, int cond
, const void *data
, size_t datalen
);
195 static int alsa_fixup(struct ast_channel
*oldchan
, struct ast_channel
*newchan
);
197 static const struct ast_channel_tech alsa_tech
= {
199 .description
= tdesc
,
200 .capabilities
= AST_FORMAT_SLINEAR
,
201 .requester
= alsa_request
,
202 .send_digit_end
= alsa_digit
,
203 .send_text
= alsa_text
,
204 .hangup
= alsa_hangup
,
205 .answer
= alsa_answer
,
209 .indicate
= alsa_indicate
,
213 static int send_sound(void)
215 short myframe
[FRAME_SIZE
];
216 int total
= FRAME_SIZE
;
218 int amt
= 0, res
, myoff
;
219 snd_pcm_state_t state
;
225 if (sampsent
< sounds
[cursound
].samplen
) {
229 if (amt
> (sounds
[cursound
].datalen
- offset
))
230 amt
= sounds
[cursound
].datalen
- offset
;
231 memcpy(myframe
+ myoff
, sounds
[cursound
].data
+ offset
, amt
* 2);
236 if (offset
>= sounds
[cursound
].datalen
)
239 /* Set it up for silence */
240 if (sampsent
>= sounds
[cursound
].samplen
)
241 silencelen
= sounds
[cursound
].silencelen
;
244 if (silencelen
> 0) {
248 if (sounds
[cursound
].repeat
) {
260 if (res
== 0 || !frame
)
264 alsa_monitor_write((char *) frame
, res
* 2);
266 state
= snd_pcm_state(alsa
.ocard
);
267 if (state
== SND_PCM_STATE_XRUN
)
268 snd_pcm_prepare(alsa
.ocard
);
269 res
= snd_pcm_writei(alsa
.ocard
, frame
, res
);
275 static void *sound_thread(void *unused
)
285 FD_SET(sndcmd
[0], &rfds
);
287 FD_SET(writedev
, &wfds
);
293 FD_SET(readdev
, &rfds
);
298 res
= ast_select(max
+ 1, &rfds
, &wfds
, NULL
, NULL
);
300 ast_log(LOG_WARNING
, "select failed: %s\n", strerror(errno
));
304 if (FD_ISSET(readdev
, &rfds
)) {
305 /* Keep the pipe going with read audio */
306 snd_pcm_state_t state
;
307 short buf
[FRAME_SIZE
];
310 state
= snd_pcm_state(alsa
.ocard
);
311 if (state
== SND_PCM_STATE_XRUN
) {
312 snd_pcm_prepare(alsa
.ocard
);
314 r
= snd_pcm_readi(alsa
.icard
, buf
, FRAME_SIZE
);
317 ast_log(LOG_ERROR
, "XRUN read\n");
319 snd_pcm_prepare(alsa
.icard
);
320 } else if (r
== -ESTRPIPE
) {
321 ast_log(LOG_ERROR
, "-ESTRPIPE\n");
322 snd_pcm_prepare(alsa
.icard
);
324 ast_log(LOG_ERROR
, "Read error: %s\n", snd_strerror(r
));
326 alsa_monitor_read((char *) buf
, r
* 2);
329 if (FD_ISSET(sndcmd
[0], &rfds
)) {
330 read(sndcmd
[0], &cursound
, sizeof(cursound
));
335 if (FD_ISSET(writedev
, &wfds
))
337 ast_log(LOG_WARNING
, "Failed to write sound\n");
343 static snd_pcm_t
*alsa_card_init(char *dev
, snd_pcm_stream_t stream
)
347 snd_pcm_t
*handle
= NULL
;
348 snd_pcm_hw_params_t
*hwparams
= NULL
;
349 snd_pcm_sw_params_t
*swparams
= NULL
;
351 snd_pcm_uframes_t period_size
= PERIOD_FRAMES
* 4;
352 /* int period_bytes = 0; */
353 snd_pcm_uframes_t buffer_size
= 0;
355 unsigned int rate
= DESIRED_RATE
;
357 unsigned int per_min
= 1;
359 /* unsigned int per_max = 8; */
360 snd_pcm_uframes_t start_threshold
, stop_threshold
;
362 err
= snd_pcm_open(&handle
, dev
, stream
, SND_PCM_NONBLOCK
);
364 ast_log(LOG_ERROR
, "snd_pcm_open failed: %s\n", snd_strerror(err
));
367 ast_log(LOG_DEBUG
, "Opening device %s in %s mode\n", dev
, (stream
== SND_PCM_STREAM_CAPTURE
) ? "read" : "write");
369 hwparams
= alloca(snd_pcm_hw_params_sizeof());
370 memset(hwparams
, 0, snd_pcm_hw_params_sizeof());
371 snd_pcm_hw_params_any(handle
, hwparams
);
373 err
= snd_pcm_hw_params_set_access(handle
, hwparams
, SND_PCM_ACCESS_RW_INTERLEAVED
);
375 ast_log(LOG_ERROR
, "set_access failed: %s\n", snd_strerror(err
));
377 err
= snd_pcm_hw_params_set_format(handle
, hwparams
, format
);
379 ast_log(LOG_ERROR
, "set_format failed: %s\n", snd_strerror(err
));
381 err
= snd_pcm_hw_params_set_channels(handle
, hwparams
, 1);
383 ast_log(LOG_ERROR
, "set_channels failed: %s\n", snd_strerror(err
));
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
);
391 err
= snd_pcm_hw_params_set_period_size_near(handle
, hwparams
, &period_size
, &direction
);
393 ast_log(LOG_ERROR
, "period_size(%ld frames) is bad: %s\n", period_size
, snd_strerror(err
));
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
);
400 ast_log(LOG_WARNING
, "Problem setting buffer size of %ld: %s\n", buffer_size
, snd_strerror(err
));
402 ast_log(LOG_DEBUG
, "Buffer size is set to %d frames\n", err
);
406 err
= snd_pcm_hw_params_set_periods_min(handle
, hwparams
, &per_min
, &direction
);
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);
412 ast_log(LOG_ERROR
, "periods_max: %s\n", snd_strerror(err
));
415 err
= snd_pcm_hw_params(handle
, hwparams
);
417 ast_log(LOG_ERROR
, "Couldn't set the new hw params: %s\n", snd_strerror(err
));
419 swparams
= alloca(snd_pcm_sw_params_sizeof());
420 memset(swparams
, 0, snd_pcm_sw_params_sizeof());
421 snd_pcm_sw_params_current(handle
, swparams
);
424 if (stream
== SND_PCM_STREAM_PLAYBACK
)
425 start_threshold
= period_size
;
429 err
= snd_pcm_sw_params_set_start_threshold(handle
, swparams
, start_threshold
);
431 ast_log(LOG_ERROR
, "start threshold: %s\n", snd_strerror(err
));
435 if (stream
== SND_PCM_STREAM_PLAYBACK
)
436 stop_threshold
= buffer_size
;
438 stop_threshold
= buffer_size
;
440 err
= snd_pcm_sw_params_set_stop_threshold(handle
, swparams
, stop_threshold
);
442 ast_log(LOG_ERROR
, "stop threshold: %s\n", snd_strerror(err
));
445 err
= snd_pcm_sw_params_set_xfer_align(handle
, swparams
, PERIOD_FRAMES
);
447 ast_log(LOG_ERROR
, "Unable to set xfer alignment: %s\n", snd_strerror(err
));
451 err
= snd_pcm_sw_params_set_silence_threshold(handle
, swparams
, silencethreshold
);
453 ast_log(LOG_ERROR
, "Unable to set silence threshold: %s\n", snd_strerror(err
));
455 err
= snd_pcm_sw_params(handle
, swparams
);
457 ast_log(LOG_ERROR
, "sw_params: %s\n", snd_strerror(err
));
459 err
= snd_pcm_poll_descriptors_count(handle
);
461 ast_log(LOG_ERROR
, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err
));
463 ast_log(LOG_DEBUG
, "Can't handle more than one device\n");
465 snd_pcm_poll_descriptors(handle
, &pfd
, err
);
466 ast_log(LOG_DEBUG
, "Acquired fd %d from the poll descriptor\n", pfd
.fd
);
468 if (stream
== SND_PCM_STREAM_CAPTURE
)
476 static int soundcard_init(void)
478 alsa
.icard
= alsa_card_init(indevname
, SND_PCM_STREAM_CAPTURE
);
479 alsa
.ocard
= alsa_card_init(outdevname
, SND_PCM_STREAM_PLAYBACK
);
481 if (!alsa
.icard
|| !alsa
.ocard
) {
482 ast_log(LOG_ERROR
, "Problem opening alsa I/O devices\n");
489 static int alsa_digit(struct ast_channel
*c
, char digit
, unsigned int duration
)
491 ast_mutex_lock(&alsalock
);
492 ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
494 ast_mutex_unlock(&alsalock
);
498 static int alsa_text(struct ast_channel
*c
, const char *text
)
500 ast_mutex_lock(&alsalock
);
501 ast_verbose(" << Console Received text %s >> \n", text
);
502 ast_mutex_unlock(&alsalock
);
506 static void grab_owner(void)
508 while (alsa
.owner
&& ast_mutex_trylock(&alsa
.owner
->lock
)) {
509 DEADLOCK_AVOIDANCE(&alsalock
);
513 static int alsa_call(struct ast_channel
*c
, char *dest
, int timeout
)
516 struct ast_frame f
= { AST_FRAME_CONTROL
};
517 ast_mutex_lock(&alsalock
);
518 ast_verbose(" << Call placed to '%s' on console >> \n", dest
);
520 ast_verbose(" << Auto-answered >> \n");
523 f
.subclass
= AST_CONTROL_ANSWER
;
524 ast_queue_frame(alsa
.owner
, &f
);
525 ast_mutex_unlock(&alsa
.owner
->lock
);
528 ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
531 f
.subclass
= AST_CONTROL_RINGING
;
532 ast_queue_frame(alsa
.owner
, &f
);
533 ast_mutex_unlock(&alsa
.owner
->lock
);
535 write(sndcmd
[1], &res
, sizeof(res
));
537 snd_pcm_prepare(alsa
.icard
);
538 snd_pcm_start(alsa
.icard
);
539 ast_mutex_unlock(&alsalock
);
543 static void answer_sound(void)
548 write(sndcmd
[1], &res
, sizeof(res
));
552 static int alsa_answer(struct ast_channel
*c
)
554 ast_mutex_lock(&alsalock
);
555 ast_verbose(" << Console call has been answered >> \n");
557 ast_setstate(c
, AST_STATE_UP
);
559 snd_pcm_prepare(alsa
.icard
);
560 snd_pcm_start(alsa
.icard
);
561 ast_mutex_unlock(&alsalock
);
565 static int alsa_hangup(struct ast_channel
*c
)
568 ast_mutex_lock(&alsalock
);
572 ast_verbose(" << Hangup on console >> \n");
573 ast_module_unref(ast_module_info
->self
);
577 /* Congestion noise */
579 write(sndcmd
[1], &res
, sizeof(res
));
582 snd_pcm_drop(alsa
.icard
);
583 ast_mutex_unlock(&alsalock
);
587 static int alsa_write(struct ast_channel
*chan
, struct ast_frame
*f
)
589 static char sizbuf
[8000];
590 static int sizpos
= 0;
594 /* size_t frames = 0; */
595 snd_pcm_state_t state
;
597 /* Immediately return if no sound is enabled */
601 ast_mutex_lock(&alsalock
);
602 /* Stop any currently playing sound */
603 if (cursound
!= -1) {
604 snd_pcm_drop(alsa
.ocard
);
605 snd_pcm_prepare(alsa
.ocard
);
610 /* We have to digest the frame in 160-byte portions */
611 if (f
->datalen
> sizeof(sizbuf
) - sizpos
) {
612 ast_log(LOG_WARNING
, "Frame too large\n");
615 memcpy(sizbuf
+ sizpos
, f
->data
, f
->datalen
);
619 alsa_monitor_write(sizbuf
, len
);
621 state
= snd_pcm_state(alsa
.ocard
);
622 if (state
== SND_PCM_STATE_XRUN
)
623 snd_pcm_prepare(alsa
.ocard
);
624 res
= snd_pcm_writei(alsa
.ocard
, sizbuf
, len
/ 2);
627 ast_log(LOG_DEBUG
, "XRUN write\n");
629 snd_pcm_prepare(alsa
.ocard
);
630 res
= snd_pcm_writei(alsa
.ocard
, sizbuf
, len
/ 2);
631 if (res
!= len
/ 2) {
632 ast_log(LOG_ERROR
, "Write error: %s\n", snd_strerror(res
));
634 } else if (res
< 0) {
635 ast_log(LOG_ERROR
, "Write error %s\n", snd_strerror(res
));
639 if (res
== -ESTRPIPE
)
640 ast_log(LOG_ERROR
, "You've got some big problems\n");
642 ast_log(LOG_NOTICE
, "Error %d on write\n", res
);
645 ast_mutex_unlock(&alsalock
);
652 static struct ast_frame
*alsa_read(struct ast_channel
*chan
)
654 static struct ast_frame f
;
655 static short __buf
[FRAME_SIZE
+ AST_FRIENDLY_OFFSET
/ 2];
657 static int readpos
= 0;
658 static int left
= FRAME_SIZE
;
659 snd_pcm_state_t state
;
663 ast_mutex_lock(&alsalock
);
664 /* Acknowledge any pending cmd */
665 f
.frametype
= AST_FRAME_NULL
;
673 f
.delivery
.tv_sec
= 0;
674 f
.delivery
.tv_usec
= 0;
676 state
= snd_pcm_state(alsa
.icard
);
677 if ((state
!= SND_PCM_STATE_PREPARED
) && (state
!= SND_PCM_STATE_RUNNING
)) {
678 snd_pcm_prepare(alsa
.icard
);
681 buf
= __buf
+ AST_FRIENDLY_OFFSET
/ 2;
683 r
= snd_pcm_readi(alsa
.icard
, buf
+ readpos
, left
);
686 ast_log(LOG_ERROR
, "XRUN read\n");
688 snd_pcm_prepare(alsa
.icard
);
689 } else if (r
== -ESTRPIPE
) {
690 ast_log(LOG_ERROR
, "-ESTRPIPE\n");
691 snd_pcm_prepare(alsa
.icard
);
693 ast_log(LOG_ERROR
, "Read error: %s\n", snd_strerror(r
));
697 /* Update positions */
701 if (readpos
>= FRAME_SIZE
) {
705 if (chan
->_state
!= AST_STATE_UP
) {
706 /* Don't transmit unless it's up */
707 ast_mutex_unlock(&alsalock
);
710 f
.frametype
= AST_FRAME_VOICE
;
711 f
.subclass
= AST_FORMAT_SLINEAR
;
712 f
.samples
= FRAME_SIZE
;
713 f
.datalen
= FRAME_SIZE
* 2;
715 f
.offset
= AST_FRIENDLY_OFFSET
;
719 alsa_monitor_read((char *) buf
, FRAME_SIZE
* 2);
723 ast_mutex_unlock(&alsalock
);
727 static int alsa_fixup(struct ast_channel
*oldchan
, struct ast_channel
*newchan
)
729 struct chan_alsa_pvt
*p
= newchan
->tech_pvt
;
730 ast_mutex_lock(&alsalock
);
732 ast_mutex_unlock(&alsalock
);
736 static int alsa_indicate(struct ast_channel
*chan
, int cond
, const void *data
, size_t datalen
)
740 ast_mutex_lock(&alsalock
);
743 case AST_CONTROL_BUSY
:
746 case AST_CONTROL_CONGESTION
:
749 case AST_CONTROL_RINGING
:
750 case AST_CONTROL_PROGRESS
:
755 case AST_CONTROL_VIDUPDATE
:
758 case AST_CONTROL_HOLD
:
759 ast_verbose(" << Console Has Been Placed on Hold >> \n");
760 ast_moh_start(chan
, data
, mohinterpret
);
762 case AST_CONTROL_UNHOLD
:
763 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
766 case AST_CONTROL_SRCUPDATE
:
769 ast_log(LOG_WARNING
, "Don't know how to display condition %d on %s\n", cond
, chan
->name
);
774 write(sndcmd
[1], &res
, sizeof(res
));
776 ast_mutex_unlock(&alsalock
);
781 static struct ast_channel
*alsa_new(struct chan_alsa_pvt
*p
, int state
)
783 struct ast_channel
*tmp
= NULL
;
785 if (!(tmp
= ast_channel_alloc(1, state
, 0, 0, "", p
->exten
, p
->context
, 0, "ALSA/%s", indevname
)))
788 tmp
->tech
= &alsa_tech
;
789 tmp
->fds
[0] = readdev
;
790 tmp
->nativeformats
= AST_FORMAT_SLINEAR
;
791 tmp
->readformat
= AST_FORMAT_SLINEAR
;
792 tmp
->writeformat
= AST_FORMAT_SLINEAR
;
794 if (!ast_strlen_zero(p
->context
))
795 ast_copy_string(tmp
->context
, p
->context
, sizeof(tmp
->context
));
796 if (!ast_strlen_zero(p
->exten
))
797 ast_copy_string(tmp
->exten
, p
->exten
, sizeof(tmp
->exten
));
798 if (!ast_strlen_zero(language
))
799 ast_string_field_set(tmp
, language
, language
);
801 ast_module_ref(ast_module_info
->self
);
802 ast_jb_configure(tmp
, &global_jbconf
);
803 if (state
!= AST_STATE_DOWN
) {
804 if (ast_pbx_start(tmp
)) {
805 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", tmp
->name
);
814 static struct ast_channel
*alsa_request(const char *type
, int format
, void *data
, int *cause
)
816 int oldformat
= format
;
817 struct ast_channel
*tmp
= NULL
;
819 format
&= AST_FORMAT_SLINEAR
;
821 ast_log(LOG_NOTICE
, "Asked to get a channel of format '%d'\n", oldformat
);
825 ast_mutex_lock(&alsalock
);
828 ast_log(LOG_NOTICE
, "Already have a call on the ALSA channel\n");
829 *cause
= AST_CAUSE_BUSY
;
830 } else if (!(tmp
= alsa_new(&alsa
, AST_STATE_DOWN
)))
831 ast_log(LOG_WARNING
, "Unable to create new ALSA channel\n");
833 ast_mutex_unlock(&alsalock
);
838 static int console_autoanswer_deprecated(int fd
, int argc
, char *argv
[])
840 int res
= RESULT_SUCCESS
;
842 if ((argc
!= 1) && (argc
!= 2))
843 return RESULT_SHOWUSAGE
;
845 ast_mutex_lock(&alsalock
);
848 ast_cli(fd
, "Auto answer is %s.\n", autoanswer
? "on" : "off");
850 if (!strcasecmp(argv
[1], "on"))
852 else if (!strcasecmp(argv
[1], "off"))
855 res
= RESULT_SHOWUSAGE
;
858 ast_mutex_unlock(&alsalock
);
863 static int console_autoanswer(int fd
, int argc
, char *argv
[])
865 int res
= RESULT_SUCCESS
;;
866 if ((argc
!= 2) && (argc
!= 3))
867 return RESULT_SHOWUSAGE
;
868 ast_mutex_lock(&alsalock
);
870 ast_cli(fd
, "Auto answer is %s.\n", autoanswer
? "on" : "off");
872 if (!strcasecmp(argv
[2], "on"))
874 else if (!strcasecmp(argv
[2], "off"))
877 res
= RESULT_SHOWUSAGE
;
879 ast_mutex_unlock(&alsalock
);
883 static char *autoanswer_complete(const char *line
, const char *word
, int pos
, int state
)
886 #define MIN(a,b) ((a) < (b) ? (a) : (b))
890 if (!ast_strlen_zero(word
) && !strncasecmp(word
, "on", MIN(strlen(word
), 2)))
891 return ast_strdup("on");
893 if (!ast_strlen_zero(word
) && !strncasecmp(word
, "off", MIN(strlen(word
), 3)))
894 return ast_strdup("off");
901 static const char autoanswer_usage
[] =
902 "Usage: console autoanswer [on|off]\n"
903 " Enables or disables autoanswer feature. If used without\n"
904 " argument, displays the current on/off status of autoanswer.\n"
905 " The default value of autoanswer is in 'alsa.conf'.\n";
907 static int console_answer_deprecated(int fd
, int argc
, char *argv
[])
909 int res
= RESULT_SUCCESS
;
912 return RESULT_SHOWUSAGE
;
914 ast_mutex_lock(&alsalock
);
917 ast_cli(fd
, "No one is calling us\n");
918 res
= RESULT_FAILURE
;
924 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_ANSWER
};
925 ast_queue_frame(alsa
.owner
, &f
);
926 ast_mutex_unlock(&alsa
.owner
->lock
);
931 snd_pcm_prepare(alsa
.icard
);
932 snd_pcm_start(alsa
.icard
);
934 ast_mutex_unlock(&alsalock
);
936 return RESULT_SUCCESS
;
939 static int console_answer(int fd
, int argc
, char *argv
[])
941 int res
= RESULT_SUCCESS
;
944 return RESULT_SHOWUSAGE
;
946 ast_mutex_lock(&alsalock
);
949 ast_cli(fd
, "No one is calling us\n");
950 res
= RESULT_FAILURE
;
956 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_ANSWER
};
957 ast_queue_frame(alsa
.owner
, &f
);
958 ast_mutex_unlock(&alsa
.owner
->lock
);
963 snd_pcm_prepare(alsa
.icard
);
964 snd_pcm_start(alsa
.icard
);
966 ast_mutex_unlock(&alsalock
);
968 return RESULT_SUCCESS
;
971 static char sendtext_usage
[] =
972 "Usage: console send text <message>\n"
973 " Sends a text message for display on the remote terminal.\n";
975 static int console_sendtext_deprecated(int fd
, int argc
, char *argv
[])
978 int res
= RESULT_SUCCESS
;
981 return RESULT_SHOWUSAGE
;
983 ast_mutex_lock(&alsalock
);
986 ast_cli(fd
, "No one is calling us\n");
987 res
= RESULT_FAILURE
;
989 struct ast_frame f
= { AST_FRAME_TEXT
, 0 };
990 char text2send
[256] = "";
992 while (tmparg
< argc
) {
993 strncat(text2send
, argv
[tmparg
++], sizeof(text2send
) - strlen(text2send
) - 1);
994 strncat(text2send
, " ", sizeof(text2send
) - strlen(text2send
) - 1);
996 text2send
[strlen(text2send
) - 1] = '\n';
998 f
.datalen
= strlen(text2send
) + 1;
1001 ast_queue_frame(alsa
.owner
, &f
);
1002 f
.frametype
= AST_FRAME_CONTROL
;
1003 f
.subclass
= AST_CONTROL_ANSWER
;
1006 ast_queue_frame(alsa
.owner
, &f
);
1007 ast_mutex_unlock(&alsa
.owner
->lock
);
1011 ast_mutex_unlock(&alsalock
);
1016 static int console_sendtext(int fd
, int argc
, char *argv
[])
1019 int res
= RESULT_SUCCESS
;
1022 return RESULT_SHOWUSAGE
;
1024 ast_mutex_lock(&alsalock
);
1027 ast_cli(fd
, "No one is calling us\n");
1028 res
= RESULT_FAILURE
;
1030 struct ast_frame f
= { AST_FRAME_TEXT
, 0 };
1031 char text2send
[256] = "";
1032 text2send
[0] = '\0';
1033 while (tmparg
< argc
) {
1034 strncat(text2send
, argv
[tmparg
++], sizeof(text2send
) - strlen(text2send
) - 1);
1035 strncat(text2send
, " ", sizeof(text2send
) - strlen(text2send
) - 1);
1037 text2send
[strlen(text2send
) - 1] = '\n';
1039 f
.datalen
= strlen(text2send
) + 1;
1042 ast_queue_frame(alsa
.owner
, &f
);
1043 f
.frametype
= AST_FRAME_CONTROL
;
1044 f
.subclass
= AST_CONTROL_ANSWER
;
1047 ast_queue_frame(alsa
.owner
, &f
);
1048 ast_mutex_unlock(&alsa
.owner
->lock
);
1052 ast_mutex_unlock(&alsalock
);
1057 static char answer_usage
[] =
1058 "Usage: console answer\n"
1059 " Answers an incoming call on the console (ALSA) channel.\n";
1061 static int console_hangup_deprecated(int fd
, int argc
, char *argv
[])
1063 int res
= RESULT_SUCCESS
;
1066 return RESULT_SHOWUSAGE
;
1070 ast_mutex_lock(&alsalock
);
1072 if (!alsa
.owner
&& !hookstate
) {
1073 ast_cli(fd
, "No call to hangup up\n");
1074 res
= RESULT_FAILURE
;
1079 ast_queue_hangup(alsa
.owner
);
1080 ast_mutex_unlock(&alsa
.owner
->lock
);
1084 ast_mutex_unlock(&alsalock
);
1089 static int console_hangup(int fd
, int argc
, char *argv
[])
1091 int res
= RESULT_SUCCESS
;
1094 return RESULT_SHOWUSAGE
;
1098 ast_mutex_lock(&alsalock
);
1100 if (!alsa
.owner
&& !hookstate
) {
1101 ast_cli(fd
, "No call to hangup up\n");
1102 res
= RESULT_FAILURE
;
1107 ast_queue_hangup(alsa
.owner
);
1108 ast_mutex_unlock(&alsa
.owner
->lock
);
1112 ast_mutex_unlock(&alsalock
);
1117 static char hangup_usage
[] =
1118 "Usage: console hangup\n"
1119 " Hangs up any call currently placed on the console.\n";
1121 static int console_dial_deprecated(int fd
, int argc
, char *argv
[])
1123 char tmp
[256], *tmp2
;
1126 int res
= RESULT_SUCCESS
;
1128 if ((argc
!= 1) && (argc
!= 2))
1129 return RESULT_SHOWUSAGE
;
1131 ast_mutex_lock(&alsalock
);
1138 struct ast_frame f
= { AST_FRAME_DTMF
};
1141 ast_queue_frame(alsa
.owner
, &f
);
1144 ast_mutex_unlock(&alsa
.owner
->lock
);
1147 ast_cli(fd
, "You're already in a call. You can use this only to dial digits until you hangup\n");
1148 res
= RESULT_FAILURE
;
1154 char *stringp
= NULL
;
1155 ast_copy_string(tmp
, argv
[1], sizeof(tmp
));
1157 strsep(&stringp
, "@");
1158 tmp2
= strsep(&stringp
, "@");
1159 if (!ast_strlen_zero(tmp
))
1161 if (!ast_strlen_zero(tmp2
))
1164 if (ast_exists_extension(NULL
, myc
, mye
, 1, NULL
)) {
1165 ast_copy_string(alsa
.exten
, mye
, sizeof(alsa
.exten
));
1166 ast_copy_string(alsa
.context
, myc
, sizeof(alsa
.context
));
1168 alsa_new(&alsa
, AST_STATE_RINGING
);
1170 ast_cli(fd
, "No such extension '%s' in context '%s'\n", mye
, myc
);
1173 ast_mutex_unlock(&alsalock
);
1178 static int console_dial(int fd
, int argc
, char *argv
[])
1180 char tmp
[256], *tmp2
;
1183 int res
= RESULT_SUCCESS
;
1185 if ((argc
!= 2) && (argc
!= 3))
1186 return RESULT_SHOWUSAGE
;
1188 ast_mutex_lock(&alsalock
);
1195 struct ast_frame f
= { AST_FRAME_DTMF
};
1198 ast_queue_frame(alsa
.owner
, &f
);
1201 ast_mutex_unlock(&alsa
.owner
->lock
);
1204 ast_cli(fd
, "You're already in a call. You can use this only to dial digits until you hangup\n");
1205 res
= RESULT_FAILURE
;
1211 char *stringp
= NULL
;
1212 ast_copy_string(tmp
, argv
[2], sizeof(tmp
));
1214 strsep(&stringp
, "@");
1215 tmp2
= strsep(&stringp
, "@");
1216 if (!ast_strlen_zero(tmp
))
1218 if (!ast_strlen_zero(tmp2
))
1221 if (ast_exists_extension(NULL
, myc
, mye
, 1, NULL
)) {
1222 ast_copy_string(alsa
.exten
, mye
, sizeof(alsa
.exten
));
1223 ast_copy_string(alsa
.context
, myc
, sizeof(alsa
.context
));
1225 alsa_new(&alsa
, AST_STATE_RINGING
);
1227 ast_cli(fd
, "No such extension '%s' in context '%s'\n", mye
, myc
);
1230 ast_mutex_unlock(&alsalock
);
1235 static char dial_usage
[] =
1236 "Usage: console dial [extension[@context]]\n"
1237 " Dials a given extension (and context if specified)\n";
1239 static struct ast_cli_entry cli_alsa_answer_deprecated
= {
1241 console_answer_deprecated
, NULL
,
1244 static struct ast_cli_entry cli_alsa_hangup_deprecated
= {
1246 console_hangup_deprecated
, NULL
,
1249 static struct ast_cli_entry cli_alsa_dial_deprecated
= {
1251 console_dial_deprecated
, NULL
,
1254 static struct ast_cli_entry cli_alsa_send_text_deprecated
= {
1255 { "send", "text", NULL
},
1256 console_sendtext_deprecated
, NULL
,
1259 static struct ast_cli_entry cli_alsa_autoanswer_deprecated
= {
1260 { "autoanswer", NULL
},
1261 console_autoanswer_deprecated
, NULL
,
1262 NULL
, autoanswer_complete
};
1264 static struct ast_cli_entry cli_alsa
[] = {
1265 { { "console", "answer", NULL
},
1266 console_answer
, "Answer an incoming console call",
1267 answer_usage
, NULL
, &cli_alsa_answer_deprecated
},
1269 { { "console", "hangup", NULL
},
1270 console_hangup
, "Hangup a call on the console",
1271 hangup_usage
, NULL
, &cli_alsa_hangup_deprecated
},
1273 { { "console", "dial", NULL
},
1274 console_dial
, "Dial an extension on the console",
1275 dial_usage
, NULL
, &cli_alsa_dial_deprecated
},
1277 { { "console", "send", "text", NULL
},
1278 console_sendtext
, "Send text to the remote device",
1279 sendtext_usage
, NULL
, &cli_alsa_send_text_deprecated
},
1281 { { "console", "autoanswer", NULL
},
1282 console_autoanswer
, "Sets/displays autoanswer",
1283 autoanswer_usage
, autoanswer_complete
, &cli_alsa_autoanswer_deprecated
},
1286 static int load_module(void)
1289 struct ast_config
*cfg
;
1290 struct ast_variable
*v
;
1292 /* Copy the default jb config over global_jbconf */
1293 memcpy(&global_jbconf
, &default_jbconf
, sizeof(struct ast_jb_conf
));
1295 strcpy(mohinterpret
, "default");
1297 if ((cfg
= ast_config_load(config
))) {
1298 v
= ast_variable_browse(cfg
, "general");
1299 for (; v
; v
= v
->next
) {
1300 /* handle jb conf */
1301 if (!ast_jb_read_conf(&global_jbconf
, v
->name
, v
->value
))
1304 if (!strcasecmp(v
->name
, "autoanswer"))
1305 autoanswer
= ast_true(v
->value
);
1306 else if (!strcasecmp(v
->name
, "silencesuppression"))
1307 silencesuppression
= ast_true(v
->value
);
1308 else if (!strcasecmp(v
->name
, "silencethreshold"))
1309 silencethreshold
= atoi(v
->value
);
1310 else if (!strcasecmp(v
->name
, "context"))
1311 ast_copy_string(context
, v
->value
, sizeof(context
));
1312 else if (!strcasecmp(v
->name
, "language"))
1313 ast_copy_string(language
, v
->value
, sizeof(language
));
1314 else if (!strcasecmp(v
->name
, "extension"))
1315 ast_copy_string(exten
, v
->value
, sizeof(exten
));
1316 else if (!strcasecmp(v
->name
, "input_device"))
1317 ast_copy_string(indevname
, v
->value
, sizeof(indevname
));
1318 else if (!strcasecmp(v
->name
, "output_device"))
1319 ast_copy_string(outdevname
, v
->value
, sizeof(outdevname
));
1320 else if (!strcasecmp(v
->name
, "mohinterpret"))
1321 ast_copy_string(mohinterpret
, v
->value
, sizeof(mohinterpret
));
1323 ast_config_destroy(cfg
);
1327 ast_log(LOG_ERROR
, "Unable to create pipe\n");
1330 res
= soundcard_init();
1332 if (option_verbose
> 1) {
1333 ast_verbose(VERBOSE_PREFIX_2
"No sound card detected -- console channel will be unavailable\n");
1334 ast_verbose(VERBOSE_PREFIX_2
"Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
1339 res
= ast_channel_register(&alsa_tech
);
1341 ast_log(LOG_ERROR
, "Unable to register channel class 'Console'\n");
1344 ast_cli_register_multiple(cli_alsa
, sizeof(cli_alsa
) / sizeof(struct ast_cli_entry
));
1346 ast_pthread_create_background(&sthread
, NULL
, sound_thread
, NULL
);
1348 if (alsa_monitor_start())
1349 ast_log(LOG_ERROR
, "Problem starting Monitoring\n");
1354 static int unload_module(void)
1356 ast_channel_unregister(&alsa_tech
);
1357 ast_cli_unregister_multiple(cli_alsa
, sizeof(cli_alsa
) / sizeof(struct ast_cli_entry
));
1360 snd_pcm_close(alsa
.icard
);
1362 snd_pcm_close(alsa
.ocard
);
1363 if (sndcmd
[0] > 0) {
1368 ast_softhangup(alsa
.owner
, AST_SOFTHANGUP_APPUNLOAD
);
1374 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "ALSA Console Channel Driver");