Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:04 2007

Asterisk developer's documentation :: Codename Pineapple


chan_alsa.c File Reference


Detailed Description

ALSA sound card channel driver.

Author:
Matthew Fredrickson <creslin@digium.com>
See also

Definition in file chan_alsa.c.

#include "asterisk.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <alsa/asoundlib.h>
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/endian.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/musiconhold.h"
#include "busy.h"
#include "ringtone.h"
#include "ring10.h"
#include "answer.h"

Include dependency graph for chan_alsa.c:

Go to the source code of this file.

Data Structures

struct  chan_alsa_pvt
struct  sound

Defines

#define ALSA_INDEV   "hw:0,0"
#define ALSA_OUTDEV   "hw:0,0"
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#define BUFFER_FMT   ((buffersize * 10) << 16) | (0x0006);
#define DEBUG   0
#define DESIRED_RATE   8000
#define FRAME_SIZE   160
#define MAX_BUFFER_SIZE   100
#define MIN(a, b)   ((a) < (b) ? (a) : (b))
#define MIN_SWITCH_TIME   600
#define PERIOD_FRAMES   80

Functions

static int alsa_answer (struct ast_channel *c)
static int alsa_call (struct ast_channel *c, char *dest, int timeout)
static snd_pcm_t * alsa_card_init (char *dev, snd_pcm_stream_t stream)
static int alsa_digit (struct ast_channel *c, char digit, unsigned int duration)
static int alsa_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static int alsa_hangup (struct ast_channel *c)
static int alsa_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen)
static struct ast_channelalsa_new (struct chan_alsa_pvt *p, int state)
static struct ast_framealsa_read (struct ast_channel *chan)
static struct ast_channelalsa_request (const char *type, int format, void *data, int *cause)
static int alsa_text (struct ast_channel *c, const char *text)
static int alsa_write (struct ast_channel *chan, struct ast_frame *f)
static void answer_sound (void)
 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"ALSA Console Channel Driver")
 AST_MUTEX_DEFINE_STATIC (alsalock)
static char * autoanswer_complete (const char *line, const char *word, int pos, int state)
static int console_answer (int fd, int argc, char *argv[])
static int console_autoanswer (int fd, int argc, char *argv[])
static int console_dial (int fd, int argc, char *argv[])
static int console_hangup (int fd, int argc, char *argv[])
static int console_sendtext (int fd, int argc, char *argv[])
static void grab_owner (void)
static int load_module (void)
static int send_sound (void)
static void * sound_thread (void *unused)
static int soundcard_init (void)
static int unload_module (void)

Variables

static struct chan_alsa_pvt alsa
static const struct ast_channel_tech alsa_tech
static const char answer_usage []
static int autoanswer = 1
static const char autoanswer_usage []
static struct ast_cli_entry cli_alsa []
static const char config [] = "alsa.conf"
static char context [AST_MAX_CONTEXT] = "default"
static int cursound = -1
static struct ast_jb_conf default_jbconf
static const char dial_usage []
static char exten [AST_MAX_EXTENSION] = "s"
static snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE
static struct ast_jb_conf global_jbconf
static const char hangup_usage []
static int hookstate = 0
static char indevname [50] = ALSA_INDEV
static char language [MAX_LANGUAGE] = ""
static char mohinterpret [MAX_MUSICCLASS]
static int nosound = 0
static int offset = 0
static char outdevname [50] = ALSA_OUTDEV
static int readdev = -1
static int sampsent = 0
static const char sendtext_usage []
static short silence [FRAME_SIZE] = { 0, }
static int silencelen = 0
static int silencesuppression = 0
static int silencethreshold = 1000
static int sndcmd [2]
static struct sound sounds []
pthread_t sthread
static const char tdesc [] = "ALSA Console Channel Driver"
static int writedev = -1


Define Documentation

#define ALSA_INDEV   "hw:0,0"
 

Definition at line 86 of file chan_alsa.c.

#define ALSA_OUTDEV   "hw:0,0"
 

Definition at line 87 of file chan_alsa.c.

#define ALSA_PCM_NEW_HW_PARAMS_API
 

Definition at line 47 of file chan_alsa.c.

#define ALSA_PCM_NEW_SW_PARAMS_API
 

Definition at line 48 of file chan_alsa.c.

#define BUFFER_FMT   ((buffersize * 10) << 16) | (0x0006);
 

Definition at line 97 of file chan_alsa.c.

#define DEBUG   0
 

Definition at line 84 of file chan_alsa.c.

#define DESIRED_RATE   8000
 

Definition at line 88 of file chan_alsa.c.

Referenced by alsa_card_init().

#define FRAME_SIZE   160
 

Definition at line 91 of file chan_alsa.c.

Referenced by alsa_read(), oss_read(), send_sound(), sound_thread(), and soundcard_writeframe().

#define MAX_BUFFER_SIZE   100
 

Definition at line 172 of file chan_alsa.c.

#define MIN a,
 )     ((a) < (b) ? (a) : (b))
 

Referenced by autoanswer_complete(), and send_sound().

#define MIN_SWITCH_TIME   600
 

Definition at line 100 of file chan_alsa.c.

#define PERIOD_FRAMES   80
 

Definition at line 92 of file chan_alsa.c.

Referenced by alsa_card_init().


Function Documentation

static int alsa_answer struct ast_channel c  )  [static]
 

Definition at line 562 of file chan_alsa.c.

References alsa, answer_sound(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, ast_verbose(), cursound, and chan_alsa_pvt::icard.

00563 {
00564    ast_mutex_lock(&alsalock);
00565    ast_verbose(" << Console call has been answered >> \n");
00566    answer_sound();
00567    ast_setstate(c, AST_STATE_UP);
00568    cursound = -1;
00569    snd_pcm_prepare(alsa.icard);
00570    snd_pcm_start(alsa.icard);
00571    ast_mutex_unlock(&alsalock);
00572    return 0;
00573 }

static int alsa_call struct ast_channel c,
char *  dest,
int  timeout
[static]
 

Definition at line 523 of file chan_alsa.c.

References alsa, AST_CONTROL_ANSWER, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_verbose(), autoanswer, grab_owner(), chan_alsa_pvt::icard, ast_channel::lock, chan_alsa_pvt::owner, sndcmd, and ast_frame::subclass.

00524 {
00525    int res = 3;
00526    struct ast_frame f = { AST_FRAME_CONTROL };
00527    ast_mutex_lock(&alsalock);
00528    ast_verbose(" << Call placed to '%s' on console >> \n", dest);
00529    if (autoanswer) {
00530       ast_verbose(" << Auto-answered >> \n");
00531       grab_owner();
00532       if (alsa.owner) {
00533          f.subclass = AST_CONTROL_ANSWER;
00534          ast_queue_frame(alsa.owner, &f);
00535          ast_mutex_unlock(&alsa.owner->lock);
00536       }
00537    } else {
00538       ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
00539       grab_owner();
00540       if (alsa.owner) {
00541          f.subclass = AST_CONTROL_RINGING;
00542          ast_queue_frame(alsa.owner, &f);
00543          ast_mutex_unlock(&alsa.owner->lock);
00544       }
00545       write(sndcmd[1], &res, sizeof(res));
00546    }
00547    snd_pcm_prepare(alsa.icard);
00548    snd_pcm_start(alsa.icard);
00549    ast_mutex_unlock(&alsalock);
00550    return 0;
00551 }

static snd_pcm_t* alsa_card_init char *  dev,
snd_pcm_stream_t  stream
[static]
 

Definition at line 344 of file chan_alsa.c.

References ast_log(), DESIRED_RATE, pollfd::fd, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, PERIOD_FRAMES, readdev, and writedev.

Referenced by soundcard_init().

00345 {
00346    int err;
00347    int direction;
00348    snd_pcm_t *handle = NULL;
00349    snd_pcm_hw_params_t *hwparams = NULL;
00350    snd_pcm_sw_params_t *swparams = NULL;
00351    struct pollfd pfd;
00352    snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4;
00353    /* int period_bytes = 0; */
00354    snd_pcm_uframes_t buffer_size = 0;
00355 
00356    unsigned int rate = DESIRED_RATE;
00357 #if 0
00358    unsigned int per_min = 1;
00359 #endif
00360    /* unsigned int per_max = 8; */
00361    snd_pcm_uframes_t start_threshold, stop_threshold;
00362 
00363    err = snd_pcm_open(&handle, dev, stream, O_NONBLOCK);
00364    if (err < 0) {
00365       ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err));
00366       return NULL;
00367    } else {
00368       if (option_debug)
00369          ast_log(LOG_DEBUG, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write");
00370    }
00371 
00372    snd_pcm_hw_params_alloca(&hwparams);
00373    snd_pcm_hw_params_any(handle, hwparams);
00374 
00375    err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
00376    if (err < 0)
00377       ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err));
00378 
00379    err = snd_pcm_hw_params_set_format(handle, hwparams, format);
00380    if (err < 0)
00381       ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err));
00382 
00383    err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
00384    if (err < 0)
00385       ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err));
00386 
00387    direction = 0;
00388    err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction);
00389    if (rate != DESIRED_RATE)
00390       ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate);
00391 
00392    direction = 0;
00393    err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction);
00394    if (err < 0)
00395       ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err));
00396    else {
00397       if (option_debug)
00398          ast_log(LOG_DEBUG, "Period size is %d\n", err);
00399    }
00400 
00401    buffer_size = 4096 * 2;    /* period_size * 16; */
00402    err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
00403    if (err < 0)
00404       ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err));
00405    else {
00406       if (option_debug)
00407          ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err);
00408    }
00409 
00410 #if 0
00411    direction = 0;
00412    err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, &direction);
00413    if (err < 0)
00414       ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err));
00415 
00416    err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0);
00417    if (err < 0)
00418       ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err));
00419 #endif
00420 
00421    err = snd_pcm_hw_params(handle, hwparams);
00422    if (err < 0)
00423       ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err));
00424 
00425    snd_pcm_sw_params_alloca(&swparams);
00426    snd_pcm_sw_params_current(handle, swparams);
00427 
00428 #if 1
00429    if (stream == SND_PCM_STREAM_PLAYBACK)
00430       start_threshold = period_size;
00431    else
00432       start_threshold = 1;
00433 
00434    err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
00435    if (err < 0)
00436       ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err));
00437 #endif
00438 
00439 #if 1
00440    if (stream == SND_PCM_STREAM_PLAYBACK)
00441       stop_threshold = buffer_size;
00442    else
00443       stop_threshold = buffer_size;
00444 
00445    err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
00446    if (err < 0)
00447       ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err));
00448 #endif
00449 #if 0
00450    err = snd_pcm_sw_params_set_xfer_align(handle, swparams, PERIOD_FRAMES);
00451    if (err < 0)
00452       ast_log(LOG_ERROR, "Unable to set xfer alignment: %s\n", snd_strerror(err));
00453 #endif
00454 
00455 #if 0
00456    err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, silencethreshold);
00457    if (err < 0)
00458       ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err));
00459 #endif
00460    err = snd_pcm_sw_params(handle, swparams);
00461    if (err < 0)
00462       ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err));
00463 
00464    err = snd_pcm_poll_descriptors_count(handle);
00465    if (err <= 0)
00466       ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err));
00467    if (err != 1) {
00468       if (option_debug)
00469          ast_log(LOG_DEBUG, "Can't handle more than one device\n");
00470    }
00471 
00472    snd_pcm_poll_descriptors(handle, &pfd, err);
00473    if (option_debug)
00474       ast_log(LOG_DEBUG, "Acquired fd %d from the poll descriptor\n", pfd.fd);
00475 
00476    if (stream == SND_PCM_STREAM_CAPTURE)
00477       readdev = pfd.fd;
00478    else
00479       writedev = pfd.fd;
00480 
00481    return handle;
00482 }

static int alsa_digit struct ast_channel c,
char  digit,
unsigned int  duration
[static]
 

Definition at line 497 of file chan_alsa.c.

References ast_mutex_lock(), ast_mutex_unlock(), and ast_verbose().

00498 {
00499    ast_mutex_lock(&alsalock);
00500    ast_verbose(" << Console Received digit %c of duration %u ms >> \n", 
00501       digit, duration);
00502    ast_mutex_unlock(&alsalock);
00503    return 0;
00504 }

static int alsa_fixup struct ast_channel oldchan,
struct ast_channel newchan
[static]
 

Definition at line 738 of file chan_alsa.c.

References ast_mutex_lock(), ast_mutex_unlock(), chan_alsa_pvt::owner, and ast_channel::tech_pvt.

00739 {
00740    struct chan_alsa_pvt *p = newchan->tech_pvt;
00741    ast_mutex_lock(&alsalock);
00742    p->owner = newchan;
00743    ast_mutex_unlock(&alsalock);
00744    return 0;
00745 }

static int alsa_hangup struct ast_channel c  )  [static]
 

Definition at line 575 of file chan_alsa.c.

References alsa, ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), autoanswer, cursound, chan_alsa_pvt::icard, chan_alsa_pvt::owner, sndcmd, and ast_channel::tech_pvt.

00576 {
00577    int res;
00578    ast_mutex_lock(&alsalock);
00579    cursound = -1;
00580    c->tech_pvt = NULL;
00581    alsa.owner = NULL;
00582    ast_verbose(" << Hangup on console >> \n");
00583    ast_module_unref(ast_module_info->self);
00584    if (hookstate) {
00585       hookstate = 0;
00586       if (!autoanswer) {
00587          /* Congestion noise */
00588          res = 2;
00589          write(sndcmd[1], &res, sizeof(res));
00590       }
00591    }
00592    snd_pcm_drop(alsa.icard);
00593    ast_mutex_unlock(&alsalock);
00594    return 0;
00595 }

static int alsa_indicate struct ast_channel chan,
int  cond,
const void *  data,
size_t  datalen
[static]
 

Definition at line 747 of file chan_alsa.c.

References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_WARNING, and sndcmd.

00748 {
00749    int res = 0;
00750 
00751    ast_mutex_lock(&alsalock);
00752 
00753    switch (cond) {
00754       case AST_CONTROL_BUSY:
00755          res = 1;
00756          break;
00757       case AST_CONTROL_CONGESTION:
00758          res = 2;
00759          break;
00760       case AST_CONTROL_RINGING:
00761          break;
00762       case -1:
00763          res = -1;
00764          break;
00765       case AST_CONTROL_VIDUPDATE:
00766          res = -1;
00767          break;
00768       case AST_CONTROL_HOLD:
00769          ast_verbose(" << Console Has Been Placed on Hold >> \n");
00770          ast_moh_start(chan, data, mohinterpret);
00771          break;
00772       case AST_CONTROL_UNHOLD:
00773          ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
00774          ast_moh_stop(chan);
00775          break;
00776       default:
00777          ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
00778          res = -1;
00779    }
00780 
00781    if (res > -1)
00782       write(sndcmd[1], &res, sizeof(res));
00783 
00784    ast_mutex_unlock(&alsalock);
00785 
00786    return res;
00787 }

static struct ast_channel* alsa_new struct chan_alsa_pvt p,
int  state
[static]
 

Definition at line 789 of file chan_alsa.c.

References alsa_tech, ast_channel_alloc(), AST_FORMAT_SLINEAR, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_channel::context, chan_alsa_pvt::context, ast_channel::exten, chan_alsa_pvt::exten, ast_channel::fds, global_jbconf, LOG_WARNING, ast_channel::nativeformats, chan_alsa_pvt::owner, readdev, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by alsa_request(), and console_dial().

00790 {
00791    struct ast_channel *tmp = NULL;
00792 
00793    if (!(tmp = ast_channel_alloc(1, state, 0, 0, "ALSA/%s", indevname)))
00794       return NULL;
00795 
00796    tmp->tech = &alsa_tech;
00797    tmp->fds[0] = readdev;
00798    tmp->nativeformats = AST_FORMAT_SLINEAR;
00799    tmp->readformat = AST_FORMAT_SLINEAR;
00800    tmp->writeformat = AST_FORMAT_SLINEAR;
00801    tmp->tech_pvt = p;
00802    if (!ast_strlen_zero(p->context))
00803       ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
00804    if (!ast_strlen_zero(p->exten))
00805       ast_copy_string(tmp->exten, p->exten, sizeof(tmp->exten));
00806    if (!ast_strlen_zero(language))
00807       ast_string_field_set(tmp, language, language);
00808    p->owner = tmp;
00809    ast_module_ref(ast_module_info->self);
00810    ast_jb_configure(tmp, &global_jbconf);
00811    if (state != AST_STATE_DOWN) {
00812       if (ast_pbx_start(tmp)) {
00813          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
00814          ast_hangup(tmp);
00815          tmp = NULL;
00816       }
00817    }
00818 
00819    return tmp;
00820 }

static struct ast_frame * alsa_read struct ast_channel chan  )  [static]
 

Definition at line 663 of file chan_alsa.c.

References ast_channel::_state, alsa, AST_FORMAT_SLINEAR, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_UP, ast_frame::data, ast_frame::datalen, ast_frame::delivery, FRAME_SIZE, ast_frame::frametype, chan_alsa_pvt::icard, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

00664 {
00665    static struct ast_frame f;
00666    static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET / 2];
00667    short *buf;
00668    static int readpos = 0;
00669    static int left = FRAME_SIZE;
00670    snd_pcm_state_t state;
00671    int r = 0;
00672    int off = 0;
00673 
00674    ast_mutex_lock(&alsalock);
00675    /* Acknowledge any pending cmd */
00676    f.frametype = AST_FRAME_NULL;
00677    f.subclass = 0;
00678    f.samples = 0;
00679    f.datalen = 0;
00680    f.data = NULL;
00681    f.offset = 0;
00682    f.src = "Console";
00683    f.mallocd = 0;
00684    f.delivery.tv_sec = 0;
00685    f.delivery.tv_usec = 0;
00686 
00687    state = snd_pcm_state(alsa.icard);
00688    if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) {
00689       snd_pcm_prepare(alsa.icard);
00690    }
00691 
00692    buf = __buf + AST_FRIENDLY_OFFSET / 2;
00693 
00694    r = snd_pcm_readi(alsa.icard, buf + readpos, left);
00695    if (r == -EPIPE) {
00696 #if DEBUG
00697       ast_log(LOG_ERROR, "XRUN read\n");
00698 #endif
00699       snd_pcm_prepare(alsa.icard);
00700    } else if (r == -ESTRPIPE) {
00701       ast_log(LOG_ERROR, "-ESTRPIPE\n");
00702       snd_pcm_prepare(alsa.icard);
00703    } else if (r < 0) {
00704       ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
00705    } else if (r >= 0) {
00706       off -= r;
00707    }
00708    /* Update positions */
00709    readpos += r;
00710    left -= r;
00711 
00712    if (readpos >= FRAME_SIZE) {
00713       /* A real frame */
00714       readpos = 0;
00715       left = FRAME_SIZE;
00716       if (chan->_state != AST_STATE_UP) {
00717          /* Don't transmit unless it's up */
00718          ast_mutex_unlock(&alsalock);
00719          return &f;
00720       }
00721       f.frametype = AST_FRAME_VOICE;
00722       f.subclass = AST_FORMAT_SLINEAR;
00723       f.samples = FRAME_SIZE;
00724       f.datalen = FRAME_SIZE * 2;
00725       f.data = buf;
00726       f.offset = AST_FRIENDLY_OFFSET;
00727       f.src = "Console";
00728       f.mallocd = 0;
00729 #ifdef ALSA_MONITOR
00730       alsa_monitor_read((char *) buf, FRAME_SIZE * 2);
00731 #endif
00732 
00733    }
00734    ast_mutex_unlock(&alsalock);
00735    return &f;
00736 }

static struct ast_channel * alsa_request const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

Definition at line 822 of file chan_alsa.c.

References alsa, alsa_new(), AST_CAUSE_BUSY, AST_FORMAT_SLINEAR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, LOG_NOTICE, LOG_WARNING, and chan_alsa_pvt::owner.

00823 {
00824    int oldformat = format;
00825    struct ast_channel *tmp = NULL;
00826 
00827    format &= AST_FORMAT_SLINEAR;
00828    if (!format) {
00829       ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat);
00830       return NULL;
00831    }
00832 
00833    ast_mutex_lock(&alsalock);
00834 
00835    if (alsa.owner) {
00836       ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
00837       *cause = AST_CAUSE_BUSY;
00838    } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN)))
00839       ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
00840 
00841    ast_mutex_unlock(&alsalock);
00842 
00843    return tmp;
00844 }

static int alsa_text struct ast_channel c,
const char *  text
[static]
 

Definition at line 506 of file chan_alsa.c.

References ast_mutex_lock(), ast_mutex_unlock(), and ast_verbose().

00507 {
00508    ast_mutex_lock(&alsalock);
00509    ast_verbose(" << Console Received text %s >> \n", text);
00510    ast_mutex_unlock(&alsalock);
00511    return 0;
00512 }

static int alsa_write struct ast_channel chan,
struct ast_frame f
[static]
 

Definition at line 597 of file chan_alsa.c.

References alsa, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), cursound, ast_frame::data, ast_frame::datalen, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, nosound, chan_alsa_pvt::ocard, and option_debug.

00598 {
00599    static char sizbuf[8000];
00600    static int sizpos = 0;
00601    int len = sizpos;
00602    int pos;
00603    int res = 0;
00604    /* size_t frames = 0; */
00605    snd_pcm_state_t state;
00606 
00607    /* Immediately return if no sound is enabled */
00608    if (nosound)
00609       return 0;
00610 
00611    ast_mutex_lock(&alsalock);
00612    /* Stop any currently playing sound */
00613    if (cursound != -1) {
00614       snd_pcm_drop(alsa.ocard);
00615       snd_pcm_prepare(alsa.ocard);
00616       cursound = -1;
00617    }
00618 
00619 
00620    /* We have to digest the frame in 160-byte portions */
00621    if (f->datalen > sizeof(sizbuf) - sizpos) {
00622       ast_log(LOG_WARNING, "Frame too large\n");
00623       res = -1;
00624    } else {
00625       memcpy(sizbuf + sizpos, f->data, f->datalen);
00626       len += f->datalen;
00627       pos = 0;
00628 #ifdef ALSA_MONITOR
00629       alsa_monitor_write(sizbuf, len);
00630 #endif
00631       state = snd_pcm_state(alsa.ocard);
00632       if (state == SND_PCM_STATE_XRUN)
00633          snd_pcm_prepare(alsa.ocard);
00634       res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
00635       if (res == -EPIPE) {
00636 #if DEBUG
00637          if (option_debug)
00638             ast_log(LOG_DEBUG, "XRUN write\n");
00639 #endif
00640          snd_pcm_prepare(alsa.ocard);
00641          res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2);
00642          if (res != len / 2) {
00643             ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res));
00644             res = -1;
00645          } else if (res < 0) {
00646             ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res));
00647             res = -1;
00648          }
00649       } else {
00650          if (res == -ESTRPIPE)
00651             ast_log(LOG_ERROR, "You've got some big problems\n");
00652          else if (res < 0)
00653             ast_log(LOG_NOTICE, "Error %d on write\n", res);
00654       }
00655    }
00656    ast_mutex_unlock(&alsalock);
00657    if (res > 0)
00658       res = 0;
00659    return res;
00660 }

static void answer_sound void   )  [static]
 

Definition at line 553 of file chan_alsa.c.

References nosound, and sndcmd.

Referenced by alsa_answer(), and console_answer().

00554 {
00555    int res;
00556    nosound = 1;
00557    res = 4;
00558    write(sndcmd[1], &res, sizeof(res));
00559 
00560 }

AST_MODULE_INFO_STANDARD ASTERISK_GPL_KEY  ,
"ALSA Console Channel Driver" 
 

AST_MUTEX_DEFINE_STATIC alsalock   ) 
 

static char* autoanswer_complete const char *  line,
const char *  word,
int  pos,
int  state
[static]
 

Definition at line 866 of file chan_alsa.c.

References ast_strdup, ast_strlen_zero(), and MIN.

00867 {
00868 #ifndef MIN
00869 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00870 #endif
00871    switch (state) {
00872       case 0:
00873          if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
00874             return ast_strdup("on");
00875       case 1:
00876          if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
00877             return ast_strdup("off");
00878       default:
00879          return NULL;
00880    }
00881    return NULL;
00882 }

static int console_answer int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 890 of file chan_alsa.c.

References alsa, answer_sound(), ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), cursound, grab_owner(), chan_alsa_pvt::icard, ast_channel::lock, chan_alsa_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00891 {
00892    int res = RESULT_SUCCESS;
00893 
00894    if (argc != 2)
00895       return RESULT_SHOWUSAGE;
00896 
00897    ast_mutex_lock(&alsalock);
00898 
00899    if (!alsa.owner) {
00900       ast_cli(fd, "No one is calling us\n");
00901       res = RESULT_FAILURE;
00902    } else {
00903       hookstate = 1;
00904       cursound = -1;
00905       grab_owner();
00906       if (alsa.owner) {
00907          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
00908          ast_queue_frame(alsa.owner, &f);
00909          ast_mutex_unlock(&alsa.owner->lock);
00910       }
00911       answer_sound();
00912    }
00913 
00914    snd_pcm_prepare(alsa.icard);
00915    snd_pcm_start(alsa.icard);
00916 
00917    ast_mutex_unlock(&alsalock);
00918 
00919    return RESULT_SUCCESS;
00920 }

static int console_autoanswer int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 846 of file chan_alsa.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), autoanswer, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00847 {
00848    int res = RESULT_SUCCESS;;
00849    if ((argc != 2) && (argc != 3))
00850       return RESULT_SHOWUSAGE;
00851    ast_mutex_lock(&alsalock);
00852    if (argc == 2) {
00853       ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
00854    } else {
00855       if (!strcasecmp(argv[2], "on"))
00856          autoanswer = -1;
00857       else if (!strcasecmp(argv[2], "off"))
00858          autoanswer = 0;
00859       else
00860          res = RESULT_SHOWUSAGE;
00861    }
00862    ast_mutex_unlock(&alsalock);
00863    return res;
00864 }

static int console_dial int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1003 of file chan_alsa.c.

References alsa, alsa_new(), ast_cli(), ast_exists_extension(), AST_FRAME_DTMF, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), AST_STATE_RINGING, ast_strlen_zero(), chan_alsa_pvt::context, chan_alsa_pvt::exten, grab_owner(), ast_channel::lock, chan_alsa_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, strsep(), and ast_frame::subclass.

01004 {
01005    char tmp[256], *tmp2;
01006    char *mye, *myc;
01007    char *d;
01008    int res = RESULT_SUCCESS;
01009 
01010    if ((argc != 2) && (argc != 3))
01011       return RESULT_SHOWUSAGE;
01012 
01013    ast_mutex_lock(&alsalock);
01014 
01015    if (alsa.owner) {
01016       if (argc == 3) {
01017          d = argv[2];
01018          grab_owner();
01019          if (alsa.owner) {
01020             struct ast_frame f = { AST_FRAME_DTMF };
01021             while (*d) {
01022                f.subclass = *d;
01023                ast_queue_frame(alsa.owner, &f);
01024                d++;
01025             }
01026             ast_mutex_unlock(&alsa.owner->lock);
01027          }
01028       } else {
01029          ast_cli(fd, "You're already in a call.  You can use this only to dial digits until you hangup\n");
01030          res = RESULT_FAILURE;
01031       }
01032    } else {
01033       mye = exten;
01034       myc = context;
01035       if (argc == 3) {
01036          char *stringp = NULL;
01037          ast_copy_string(tmp, argv[2], sizeof(tmp));
01038          stringp = tmp;
01039          strsep(&stringp, "@");
01040          tmp2 = strsep(&stringp, "@");
01041          if (!ast_strlen_zero(tmp))
01042             mye = tmp;
01043          if (!ast_strlen_zero(tmp2))
01044             myc = tmp2;
01045       }
01046       if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
01047          ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
01048          ast_copy_string(alsa.context, myc, sizeof(alsa.context));
01049          hookstate = 1;
01050          alsa_new(&alsa, AST_STATE_RINGING);
01051       } else
01052          ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
01053    }
01054 
01055    ast_mutex_unlock(&alsalock);
01056 
01057    return res;
01058 }

static int console_hangup int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 971 of file chan_alsa.c.

References alsa, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), cursound, grab_owner(), ast_channel::lock, chan_alsa_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00972 {
00973    int res = RESULT_SUCCESS;
00974 
00975    if (argc != 2)
00976       return RESULT_SHOWUSAGE;
00977 
00978    cursound = -1;
00979 
00980    ast_mutex_lock(&alsalock);
00981 
00982    if (!alsa.owner && !hookstate) {
00983       ast_cli(fd, "No call to hangup up\n");
00984       res = RESULT_FAILURE;
00985    } else {
00986       hookstate = 0;
00987       grab_owner();
00988       if (alsa.owner) {
00989          ast_queue_hangup(alsa.owner);
00990          ast_mutex_unlock(&alsa.owner->lock);
00991       }
00992    }
00993 
00994    ast_mutex_unlock(&alsalock);
00995 
00996    return res;
00997 }

static int console_sendtext int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 926 of file chan_alsa.c.

References alsa, ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, grab_owner(), ast_channel::lock, chan_alsa_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_frame::subclass.

00927 {
00928    int tmparg = 3;
00929    int res = RESULT_SUCCESS;
00930 
00931    if (argc < 3)
00932       return RESULT_SHOWUSAGE;
00933 
00934    ast_mutex_lock(&alsalock);
00935 
00936    if (!alsa.owner) {
00937       ast_cli(fd, "No one is calling us\n");
00938       res = RESULT_FAILURE;
00939    } else {
00940       struct ast_frame f = { AST_FRAME_TEXT, 0 };
00941       char text2send[256] = "";
00942       text2send[0] = '\0';
00943       while (tmparg < argc) {
00944          strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
00945          strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
00946       }
00947       text2send[strlen(text2send) - 1] = '\n';
00948       f.data = text2send;
00949       f.datalen = strlen(text2send) + 1;
00950       grab_owner();
00951       if (alsa.owner) {
00952          ast_queue_frame(alsa.owner, &f);
00953          f.frametype = AST_FRAME_CONTROL;
00954          f.subclass = AST_CONTROL_ANSWER;
00955          f.data = NULL;
00956          f.datalen = 0;
00957          ast_queue_frame(alsa.owner, &f);
00958          ast_mutex_unlock(&alsa.owner->lock);
00959       }
00960    }
00961 
00962    ast_mutex_unlock(&alsalock);
00963 
00964    return res;
00965 }

static void grab_owner void   )  [static]
 

Definition at line 514 of file chan_alsa.c.

References alsa, ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_channel::lock, and chan_alsa_pvt::owner.

Referenced by alsa_call(), console_answer(), console_dial(), console_hangup(), and console_sendtext().

00515 {
00516    while (alsa.owner && ast_mutex_trylock(&alsa.owner->lock)) {
00517       ast_mutex_unlock(&alsalock);
00518       usleep(1);
00519       ast_mutex_lock(&alsalock);
00520    }
00521 }

static int load_module void   )  [static]
 

Definition at line 1086 of file chan_alsa.c.

References ast_config_load(), ast_jb_read_conf(), AST_MODULE_LOAD_DECLINE, ast_true(), ast_variable_browse(), autoanswer, default_jbconf, global_jbconf, ast_variable::name, ast_variable::next, and ast_variable::value.

01087 {
01088    struct ast_config *cfg;
01089    struct ast_variable *v;
01090 
01091    /* Copy the default jb config over global_jbconf */
01092    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
01093 
01094    strcpy(mohinterpret, "default");
01095 
01096    if (!(cfg = ast_config_load(config)))
01097       return AST_MODULE_LOAD_DECLINE;
01098 
01099    v = ast_variable_browse(cfg, "general");
01100    for (; v; v = v->next) {
01101       /* handle jb conf */
01102       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
01103             continue;
01104       
01105       if (!strcasecmp(v->name, "autoanswer"))
01106          autoanswer = ast_true(v->value);
01107       else if (!strcasecmp(v->name, "silencesuppression"))
01108          silencesuppression = ast_true(v->value);
01109       else if (!strcasecmp(v->name, "silencethreshold"))
01110          silencethreshold = atoi(v->value);
01111       else if (!strcasecmp(v->name, "context"))
01112          ast_copy_string(context, v->value, sizeof(context));
01113       else if (!strcasecmp(v->name, "language"))
01114          ast_copy_string(language, v->value, sizeof(language));
01115       else if (!strcasecmp(v->name, "extension"))
01116          ast_copy_string(exten, v->value, sizeof(exten));
01117       else if (!strcasecmp(v->name, "input_device"))
01118          ast_copy_string(indevname, v->value, sizeof(indevname));
01119       else if (!strcasecmp(v->name, "output_device"))
01120          ast_copy_string(outdevname, v->value, sizeof(outdevname));
01121       else if (!strcasecmp(v->name, "mohinterpret"))
01122          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
01123    }
01124    ast_config_destroy(cfg);
01125 
01126    if (pipe(sndcmd)) {
01127       ast_log(LOG_ERROR, "Unable to create pipe\n");
01128       return AST_MODULE_LOAD_FAILURE;
01129    }
01130 
01131    if (soundcard_init() < 0) {
01132       if (option_verbose > 1) {
01133          ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
01134          ast_verbose(VERBOSE_PREFIX_2 "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
01135       }
01136       return AST_MODULE_LOAD_DECLINE;
01137    }
01138 
01139    if (ast_channel_register(&alsa_tech)) {
01140       ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
01141       return AST_MODULE_LOAD_FAILURE;
01142    }
01143 
01144    ast_cli_register_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
01145 
01146    ast_pthread_create_background(&sthread, NULL, sound_thread, NULL);
01147 #ifdef ALSA_MONITOR
01148    if (alsa_monitor_start())
01149       ast_log(LOG_ERROR, "Problem starting Monitoring\n");
01150 #endif
01151    return AST_MODULE_LOAD_SUCCESS;
01152 }

static int send_sound void   )  [static]
 

Definition at line 214 of file chan_alsa.c.

References alsa, sound::datalen, FRAME_SIZE, chan_alsa_pvt::ocard, sound::silencelen, sounds, and total.

Referenced by sound_thread().

00215 {
00216    short myframe[FRAME_SIZE];
00217    int total = FRAME_SIZE;
00218    short *frame = NULL;
00219    int amt = 0, res, myoff;
00220    snd_pcm_state_t state;
00221 
00222    if (cursound == -1)
00223       return 0;
00224 
00225    res = total;
00226    if (sampsent < sounds[cursound].samplen) {
00227       myoff = 0;
00228       while (total) {
00229          amt = total;
00230          if (amt > (sounds[cursound].datalen - offset))
00231             amt = sounds[cursound].datalen - offset;
00232          memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
00233          total -= amt;
00234          offset += amt;
00235          sampsent += amt;
00236          myoff += amt;
00237          if (offset >= sounds[cursound].datalen)
00238             offset = 0;
00239       }
00240       /* Set it up for silence */
00241       if (sampsent >= sounds[cursound].samplen)
00242          silencelen = sounds[cursound].silencelen;
00243       frame = myframe;
00244    } else {
00245       if (silencelen > 0) {
00246          frame = silence;
00247          silencelen -= res;
00248       } else {
00249          if (sounds[cursound].repeat) {
00250             /* Start over */
00251             sampsent = 0;
00252             offset = 0;
00253          } else {
00254             cursound = -1;
00255             nosound = 0;
00256          }
00257          return 0;
00258       }
00259    }
00260 
00261    if (res == 0 || !frame)
00262       return 0;
00263 
00264 #ifdef ALSA_MONITOR
00265    alsa_monitor_write((char *) frame, res * 2);
00266 #endif
00267    state = snd_pcm_state(alsa.ocard);
00268    if (state == SND_PCM_STATE_XRUN)
00269       snd_pcm_prepare(alsa.ocard);
00270    res = snd_pcm_writei(alsa.ocard, frame, res);
00271    if (res > 0)
00272       return 0;
00273    return 0;
00274 }

static void* sound_thread void *  unused  )  [static]
 

Definition at line 276 of file chan_alsa.c.

References alsa, ast_log(), ast_select(), FRAME_SIZE, chan_alsa_pvt::icard, LOG_ERROR, LOG_WARNING, chan_alsa_pvt::ocard, chan_alsa_pvt::owner, ast_channel_tech::read, and send_sound().

00277 {
00278    fd_set rfds;
00279    fd_set wfds;
00280    int max, res;
00281 
00282    for (;;) {
00283       FD_ZERO(&rfds);
00284       FD_ZERO(&wfds);
00285       max = sndcmd[0];
00286       FD_SET(sndcmd[0], &rfds);
00287       if (cursound > -1) {
00288          FD_SET(writedev, &wfds);
00289          if (writedev > max)
00290             max = writedev;
00291       }
00292 #ifdef ALSA_MONITOR
00293       if (!alsa.owner) {
00294          FD_SET(readdev, &rfds);
00295          if (readdev > max)
00296             max = readdev;
00297       }
00298 #endif
00299       res = ast_select(max + 1, &rfds, &wfds, NULL, NULL);
00300       if (res < 1) {
00301          ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
00302          continue;
00303       }
00304 #ifdef ALSA_MONITOR
00305       if (FD_ISSET(readdev, &rfds)) {
00306          /* Keep the pipe going with read audio */
00307          snd_pcm_state_t state;
00308          short buf[FRAME_SIZE];
00309          int r;
00310 
00311          state = snd_pcm_state(alsa.ocard);
00312          if (state == SND_PCM_STATE_XRUN) {
00313             snd_pcm_prepare(alsa.ocard);
00314          }
00315          r = snd_pcm_readi(alsa.icard, buf, FRAME_SIZE);
00316          if (r == -EPIPE) {
00317 #if DEBUG
00318             ast_log(LOG_ERROR, "XRUN read\n");
00319 #endif
00320             snd_pcm_prepare(alsa.icard);
00321          } else if (r == -ESTRPIPE) {
00322             ast_log(LOG_ERROR, "-ESTRPIPE\n");
00323             snd_pcm_prepare(alsa.icard);
00324          } else if (r < 0) {
00325             ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
00326          } else
00327             alsa_monitor_read((char *) buf, r * 2);
00328       }
00329 #endif
00330       if (FD_ISSET(sndcmd[0], &rfds)) {
00331          read(sndcmd[0], &cursound, sizeof(cursound));
00332          silencelen = 0;
00333          offset = 0;
00334          sampsent = 0;
00335       }
00336       if (FD_ISSET(writedev, &wfds))
00337          if (send_sound())
00338             ast_log(LOG_WARNING, "Failed to write sound\n");
00339    }
00340    /* Never reached */
00341    return NULL;
00342 }

static int soundcard_init void   )  [static]
 

Definition at line 484 of file chan_alsa.c.

References alsa, alsa_card_init(), ast_log(), chan_alsa_pvt::icard, LOG_ERROR, chan_alsa_pvt::ocard, and readdev.

00485 {
00486    alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE);
00487    alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK);
00488 
00489    if (!alsa.icard || !alsa.ocard) {
00490       ast_log(LOG_ERROR, "Problem opening alsa I/O devices\n");
00491       return -1;
00492    }
00493 
00494    return readdev;
00495 }

static int unload_module void   )  [static]
 

Definition at line 1154 of file chan_alsa.c.

References alsa, alsa_tech, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, chan_alsa_pvt::icard, chan_alsa_pvt::ocard, chan_alsa_pvt::owner, and sndcmd.

01155 {
01156    ast_channel_unregister(&alsa_tech);
01157    ast_cli_unregister_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
01158 
01159    if (alsa.icard)
01160       snd_pcm_close(alsa.icard);
01161    if (alsa.ocard)
01162       snd_pcm_close(alsa.ocard);
01163    if (sndcmd[0] > 0) {
01164       close(sndcmd[0]);
01165       close(sndcmd[1]);
01166    }
01167    if (alsa.owner)
01168       ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
01169    if (alsa.owner)
01170       return -1;
01171    return 0;
01172 }


Variable Documentation

struct chan_alsa_pvt alsa [static]
 

Referenced by alsa_answer(), alsa_call(), alsa_hangup(), alsa_read(), alsa_request(), alsa_write(), console_answer(), console_dial(), console_hangup(), console_sendtext(), grab_owner(), send_sound(), sound_thread(), soundcard_init(), and unload_module().

const struct ast_channel_tech alsa_tech [static]
 

Definition at line 198 of file chan_alsa.c.

Referenced by alsa_new(), and unload_module().

const char answer_usage[] [static]
 

Initial value:

   "Usage: console answer\n"
   "       Answers an incoming call on the console (ALSA) channel.\n"

Definition at line 967 of file chan_alsa.c.

int autoanswer = 1 [static]
 

Definition at line 178 of file chan_alsa.c.

Referenced by alsa_call(), alsa_hangup(), console_autoanswer(), and load_module().

const char autoanswer_usage[] [static]
 

Initial value:

   "Usage: console autoanswer [on|off]\n"
   "       Enables or disables autoanswer feature.  If used without\n"
   "       argument, displays the current on/off status of autoanswer.\n"
   "       The default value of autoanswer is in 'alsa.conf'.\n"

Definition at line 884 of file chan_alsa.c.

struct ast_cli_entry cli_alsa[] [static]
 

Definition at line 1064 of file chan_alsa.c.

const char config[] = "alsa.conf" [static]
 

Definition at line 122 of file chan_alsa.c.

char context[AST_MAX_CONTEXT] = "default" [static]
 

Definition at line 124 of file chan_alsa.c.

Referenced by __login_exec(), action_extensionstate(), action_originate(), action_redirect(), ast_compile_ael2(), ast_get_enum(), ast_get_srv(), ast_get_txt(), build_device(), build_gateway(), check_peer_ok(), check_user_full(), check_user_ok(), complete_context_add_include(), complete_context_remove_extension(), complete_context_remove_include(), create_addr_from_peer(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundifunc_read(), get_also_info(), get_destination(), gtalk_load_config(), handle_context_remove_extension(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), handle_show_dialplan(), jingle_load_config(), manager_show_dialplan(), metermaidstate(), orig_exten(), process_ast_dsp(), process_precache(), register_peer_exten(), reload_config(), set_device_defaults(), SHA1Input(), SHA1PadMessage(), SHA1ProcessMessageBlock(), SHA1Reset(), SHA1Result(), sip_alloc(), and unreference_cached_app().

int cursound = -1 [static]
 

Definition at line 180 of file chan_alsa.c.

Referenced by alsa_answer(), alsa_hangup(), alsa_write(), console_answer(), and console_hangup().

struct ast_jb_conf default_jbconf [static]
 

Global jitterbuffer configuration - by default, jb is disabled

Definition at line 76 of file chan_alsa.c.

Referenced by gtalk_load_config(), jingle_load_config(), load_module(), reload_config(), and setup_zap().

const char dial_usage[] [static]
 

Initial value:

   "Usage: console dial [extension[@context]]\n"
   "       Dials a given extension (and context if specified)\n"

Definition at line 1060 of file chan_alsa.c.

char exten[AST_MAX_EXTENSION] = "s" [static]
 

Definition at line 126 of file chan_alsa.c.

Referenced by action_extensionstate(), action_originate(), action_redirect(), add_extensions(), ast_compile_ael2(), ast_context_remove_extension2(), ast_feature_interpret(), ast_get_extension_context(), ast_get_extension_label(), ast_get_extension_name(), ast_get_extension_priority(), ast_ivr_menu_run_internal(), ast_parseable_goto(), ast_walk_context_extensions(), ast_walk_extension_priorities(), build_device(), check_access(), check_user_full(), complete_context_remove_extension(), complete_dpreply(), destroy_extensions(), fix_gotos_in_extensions(), gen_prios(), get_destination(), get_rdnis(), gtalk_alloc(), handle_context_add_extension(), handle_context_remove_extension(), handle_request_invite(), handle_show_dialplan(), handle_showfeatures(), linkexten(), linkprio(), manager_show_dialplan(), metermaidstate(), mgcp_ss(), new_iax(), orig_exten(), park_add_hints(), register_verify(), remap_feature(), set_priorities(), skinny_ss(), socket_process(), ss_thread(), transmit_register(), unmap_features(), and waitstream_core().

snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE [static]
 

Definition at line 103 of file chan_alsa.c.

Referenced by add_codec_to_answer(), ast_getformatbyname(), ast_monitor_stop(), ast_openvstream(), ast_parse_allow_disallow(), ast_rtp_lookup_mime_multiple(), build_device(), build_user(), handle_saydatetime(), handle_showfeatures(), handle_showmancmds(), handle_showmanconn(), reload_config(), set_config(), socket_process(), start_monitor_action(), and start_monitor_exec().

struct ast_jb_conf global_jbconf [static]
 

Definition at line 82 of file chan_alsa.c.

Referenced by __oh323_rtp_create(), __oh323_update_info(), alsa_new(), gtalk_load_config(), gtalk_new(), jingle_load_config(), jingle_new(), load_module(), mgcp_new(), oss_new(), process_zap(), reload_config(), setup_zap(), sip_get_rtp_peer(), sip_new(), sip_show_settings(), skinny_new(), and store_config().

const char hangup_usage[] [static]
 

Initial value:

   "Usage: console hangup\n"
   "       Hangs up any call currently placed on the console.\n"

Definition at line 999 of file chan_alsa.c.

int hookstate = 0 [static]
 

Definition at line 129 of file chan_alsa.c.

char indevname[50] = ALSA_INDEV [static]
 

Definition at line 109 of file chan_alsa.c.

char language[MAX_LANGUAGE] = "" [static]
 

Definition at line 125 of file chan_alsa.c.

Referenced by agent_new(), begin_dial(), build_device(), build_gateway(), check_peer_ok(), check_user_full(), check_user_ok(), features_call(), gtalk_new(), jingle_new(), local_call(), mgcp_new(), nbs_new(), oss_new(), read_config(), sip_new(), and skinny_new().

char mohinterpret[MAX_MUSICCLASS] [static]
 

Definition at line 127 of file chan_alsa.c.

Referenced by build_device(), check_peer_ok(), check_user_full(), check_user_ok(), create_addr_from_peer(), and sip_alloc().

int nosound = 0 [static]
 

Definition at line 184 of file chan_alsa.c.

Referenced by alsa_write(), and answer_sound().

int offset = 0 [static]
 

Definition at line 183 of file chan_alsa.c.

Referenced by __ast_str_helper(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_gr(), ast_say_date_with_format_he(), ast_say_date_with_format_it(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_tw(), ast_slinfactory_read(), cliinput(), copy_request(), fileexists_core(), pbx_retrieve_variable(), pbx_substitute_variables_helper_full(), resynch_jb(), and strcasestr().

char outdevname[50] = ALSA_OUTDEV [static]
 

Definition at line 110 of file chan_alsa.c.

int readdev = -1 [static]
 

Definition at line 175 of file chan_alsa.c.

Referenced by alsa_card_init(), alsa_new(), and soundcard_init().

int sampsent = 0 [static]
 

Definition at line 181 of file chan_alsa.c.

const char sendtext_usage[] [static]
 

Initial value:

   "Usage: console send text <message>\n"
   "       Sends a text message for display on the remote terminal.\n"

Definition at line 922 of file chan_alsa.c.

short silence[FRAME_SIZE] = { 0, } [static]
 

Definition at line 131 of file chan_alsa.c.

Referenced by ast_dsp_process(), and handle_recordfile().

int silencelen = 0 [static]
 

Definition at line 182 of file chan_alsa.c.

int silencesuppression = 0 [static]
 

Definition at line 116 of file chan_alsa.c.

int silencethreshold = 1000 [static]
 

Definition at line 117 of file chan_alsa.c.

Referenced by ast_record_review().

int sndcmd[2] [static]
 

Definition at line 151 of file chan_alsa.c.

Referenced by alsa_call(), alsa_hangup(), alsa_indicate(), answer_sound(), and unload_module().

struct sound sounds[] [static]
 

Definition at line 142 of file chan_alsa.c.

Referenced by send_sound(), and sound_thread().

pthread_t sthread
 

Definition at line 170 of file chan_alsa.c.

const char tdesc[] = "ALSA Console Channel Driver" [static]
 

Definition at line 121 of file chan_alsa.c.

int writedev = -1 [static]
 

Definition at line 176 of file chan_alsa.c.

Referenced by alsa_card_init().


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen