--- old/chan_alsa.c 2009-11-09 08:51:10.000000000 +0000 +++ new/chan_alsa.c 2009-11-09 09:12:56.000000000 +0000 @@ -129,6 +129,8 @@ static int writedev = -1; static int autoanswer = 1; +static int mute = 0; +static int noaudiocapture = 0; static struct ast_channel *alsa_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause); static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration); @@ -265,15 +267,22 @@ static int soundcard_init(void) { - alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE); + if (!noaudiocapture) { + alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE); + if (!alsa.icard) { + ast_log(LOG_ERROR, "Problem opening alsa capture device\n"); + return -1; + } + } + alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK); - if (!alsa.icard || !alsa.ocard) { - ast_log(LOG_ERROR, "Problem opening ALSA I/O devices\n"); + if (!alsa.ocard) { + ast_log(LOG_ERROR, "Problem opening ALSA playback device\n"); return -1; } - return readdev; + return writedev; } static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration) @@ -310,6 +319,9 @@ ast_verbose(" << Call placed to '%s' on console >> \n", dest); if (autoanswer) { ast_verbose(" << Auto-answered >> \n"); + if (mute) { + ast_verbose( " << Muted >> \n" ); + } grab_owner(); if (alsa.owner) { f.subclass.integer = AST_CONTROL_ANSWER; @@ -326,8 +338,10 @@ ast_indicate(alsa.owner, AST_CONTROL_RINGING); } } - snd_pcm_prepare(alsa.icard); - snd_pcm_start(alsa.icard); + if (!noaudiocapture) { + snd_pcm_prepare(alsa.icard); + snd_pcm_start(alsa.icard); + } ast_mutex_unlock(&alsalock); return 0; @@ -338,8 +352,10 @@ ast_mutex_lock(&alsalock); ast_verbose(" << Console call has been answered >> \n"); ast_setstate(c, AST_STATE_UP); - snd_pcm_prepare(alsa.icard); - snd_pcm_start(alsa.icard); + if (!noaudiocapture) { + snd_pcm_prepare(alsa.icard); + snd_pcm_start(alsa.icard); + } ast_mutex_unlock(&alsalock); return 0; @@ -353,7 +369,9 @@ ast_verbose(" << Hangup on console >> \n"); ast_module_unref(ast_module_info->self); hookstate = 0; - snd_pcm_drop(alsa.icard); + if (!noaudiocapture) { + snd_pcm_drop(alsa.icard); + } ast_mutex_unlock(&alsalock); return 0; @@ -436,6 +454,12 @@ f.delivery.tv_sec = 0; f.delivery.tv_usec = 0; + if (noaudiocapture) { + /* Return null frame to asterisk*/ + ast_mutex_unlock(&alsalock); + return &f; + } + state = snd_pcm_state(alsa.icard); if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) { snd_pcm_prepare(alsa.icard); @@ -470,6 +494,12 @@ ast_mutex_unlock(&alsalock); return &f; } + if (mute) { + /* Don't transmit if muted */ + ast_mutex_unlock(&alsalock); + return &f; + } + f.frametype = AST_FRAME_VOICE; f.subclass.codec = AST_FORMAT_SLINEAR; f.samples = FRAME_SIZE; @@ -667,6 +697,9 @@ ast_cli(a->fd, "No one is calling us\n"); res = CLI_FAILURE; } else { + if (mute) { + ast_verbose( " << Muted >> \n" ); + } hookstate = 1; grab_owner(); if (alsa.owner) { @@ -675,8 +708,10 @@ } } - snd_pcm_prepare(alsa.icard); - snd_pcm_start(alsa.icard); + if (!noaudiocapture) { + snd_pcm_prepare(alsa.icard); + snd_pcm_start(alsa.icard); + } ast_mutex_unlock(&alsalock); @@ -835,12 +870,57 @@ return res; } +static char *console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +{ + int toggle = 0; + char *res = CLI_SUCCESS; + + switch (cmd) { + case CLI_INIT: + e->command = "console {mute|unmute} [toggle]"; + e->usage = + "Usage: console {mute|unmute} [toggle]\n" + " Mute/unmute the microphone.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + + if (a->argc > 3) { + return CLI_SHOWUSAGE; + } + + if (a->argc == 3) { + if (strcasecmp(a->argv[2], "toggle")) + return CLI_SHOWUSAGE; + toggle = 1; + } + + if (a->argc < 2) { + return CLI_SHOWUSAGE; + } + + if (!strcasecmp(a->argv[1], "mute")) { + mute = toggle ? ~mute : 1; + } else if (!strcasecmp(a->argv[1], "unmute")) { + mute = toggle ? ~mute : 0; + } else { + return CLI_SHOWUSAGE; + } + + ast_cli(a->fd, "Console mic is %s\n", mute ? "off" : "on"); + + return res; +} + static struct ast_cli_entry cli_alsa[] = { AST_CLI_DEFINE(console_answer, "Answer an incoming console call"), AST_CLI_DEFINE(console_hangup, "Hangup a call on the console"), AST_CLI_DEFINE(console_dial, "Dial an extension on the console"), AST_CLI_DEFINE(console_sendtext, "Send text to the remote device"), AST_CLI_DEFINE(console_autoanswer, "Sets/displays autoanswer"), + AST_CLI_DEFINE(console_mute, "Disable/Enable mic input"), }; static int load_module(void) @@ -865,27 +945,33 @@ v = ast_variable_browse(cfg, "general"); for (; v; v = v->next) { /* handle jb conf */ - if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) - continue; - - if (!strcasecmp(v->name, "autoanswer")) + if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) { + continue; + } + + if (!strcasecmp(v->name, "autoanswer")) { autoanswer = ast_true(v->value); - else if (!strcasecmp(v->name, "silencesuppression")) + } else if (!strcasecmp(v->name, "mute")) { + mute = ast_true(v->value); + } else if (!strcasecmp(v->name, "noaudiocapture")) { + noaudiocapture = ast_true(v->value); + } else if (!strcasecmp(v->name, "silencesuppression")) { silencesuppression = ast_true(v->value); - else if (!strcasecmp(v->name, "silencethreshold")) + } else if (!strcasecmp(v->name, "silencethreshold")) { silencethreshold = atoi(v->value); - else if (!strcasecmp(v->name, "context")) + } else if (!strcasecmp(v->name, "context")) { ast_copy_string(context, v->value, sizeof(context)); - else if (!strcasecmp(v->name, "language")) + } else if (!strcasecmp(v->name, "language")) { ast_copy_string(language, v->value, sizeof(language)); - else if (!strcasecmp(v->name, "extension")) + } else if (!strcasecmp(v->name, "extension")) { ast_copy_string(exten, v->value, sizeof(exten)); - else if (!strcasecmp(v->name, "input_device")) + } else if (!strcasecmp(v->name, "input_device")) { ast_copy_string(indevname, v->value, sizeof(indevname)); - else if (!strcasecmp(v->name, "output_device")) + } else if (!strcasecmp(v->name, "output_device")) { ast_copy_string(outdevname, v->value, sizeof(outdevname)); - else if (!strcasecmp(v->name, "mohinterpret")) + } else if (!strcasecmp(v->name, "mohinterpret")) { ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); + } } ast_config_destroy(cfg);