aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_alsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_alsa.c')
-rw-r--r--channels/chan_alsa.c270
1 files changed, 246 insertions, 24 deletions
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 7dfd55df7..c3a4315e7 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -841,7 +841,7 @@ static struct ast_channel *alsa_request(const char *type, int format, void *data
return tmp;
}
-static int console_autoanswer(int fd, int argc, char *argv[])
+static int console_autoanswer_deprecated(int fd, int argc, char *argv[])
{
int res = RESULT_SUCCESS;
@@ -866,6 +866,26 @@ static int console_autoanswer(int fd, int argc, char *argv[])
return res;
}
+static int console_autoanswer(int fd, int argc, char *argv[])
+{
+ int res = RESULT_SUCCESS;;
+ if ((argc != 2) && (argc != 3))
+ return RESULT_SHOWUSAGE;
+ ast_mutex_lock(&alsalock);
+ if (argc == 2) {
+ ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
+ } else {
+ if (!strcasecmp(argv[2], "on"))
+ autoanswer = -1;
+ else if (!strcasecmp(argv[2], "off"))
+ autoanswer = 0;
+ else
+ res = RESULT_SHOWUSAGE;
+ }
+ ast_mutex_unlock(&alsalock);
+ return res;
+}
+
static char *autoanswer_complete(const char *line, const char *word, int pos, int state)
{
#ifndef MIN
@@ -885,11 +905,12 @@ static char *autoanswer_complete(const char *line, const char *word, int pos, in
}
static const char autoanswer_usage[] =
- "Usage: autoanswer [on|off]\n"
+ "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";
+ " argument, displays the current on/off status of autoanswer.\n"
+ " The default value of autoanswer is in 'alsa.conf'.\n";
-static int console_answer(int fd, int argc, char *argv[])
+static int console_answer_deprecated(int fd, int argc, char *argv[])
{
int res = RESULT_SUCCESS;
@@ -921,9 +942,43 @@ static int console_answer(int fd, int argc, char *argv[])
return RESULT_SUCCESS;
}
-static char sendtext_usage[] = "Usage: send text <message>\n" " Sends a text message for display on the remote terminal.\n";
+static int console_answer(int fd, int argc, char *argv[])
+{
+ int res = RESULT_SUCCESS;
-static int console_sendtext(int fd, int argc, char *argv[])
+ if (argc != 2)
+ return RESULT_SHOWUSAGE;
+
+ ast_mutex_lock(&alsalock);
+
+ if (!alsa.owner) {
+ ast_cli(fd, "No one is calling us\n");
+ res = RESULT_FAILURE;
+ } else {
+ hookstate = 1;
+ cursound = -1;
+ grab_owner();
+ if (alsa.owner) {
+ struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
+ ast_queue_frame(alsa.owner, &f);
+ ast_mutex_unlock(&alsa.owner->lock);
+ }
+ answer_sound();
+ }
+
+ snd_pcm_prepare(alsa.icard);
+ snd_pcm_start(alsa.icard);
+
+ ast_mutex_unlock(&alsalock);
+
+ return RESULT_SUCCESS;
+}
+
+static char sendtext_usage[] =
+ "Usage: console send text <message>\n"
+ " Sends a text message for display on the remote terminal.\n";
+
+static int console_sendtext_deprecated(int fd, int argc, char *argv[])
{
int tmparg = 2;
int res = RESULT_SUCCESS;
@@ -964,9 +1019,52 @@ static int console_sendtext(int fd, int argc, char *argv[])
return res;
}
-static char answer_usage[] = "Usage: answer\n" " Answers an incoming call on the console (ALSA) channel.\n";
+static int console_sendtext(int fd, int argc, char *argv[])
+{
+ int tmparg = 3;
+ int res = RESULT_SUCCESS;
-static int console_hangup(int fd, int argc, char *argv[])
+ if (argc < 3)
+ return RESULT_SHOWUSAGE;
+
+ ast_mutex_lock(&alsalock);
+
+ if (!alsa.owner) {
+ ast_cli(fd, "No one is calling us\n");
+ res = RESULT_FAILURE;
+ } else {
+ struct ast_frame f = { AST_FRAME_TEXT, 0 };
+ char text2send[256] = "";
+ text2send[0] = '\0';
+ while (tmparg < argc) {
+ strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
+ strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
+ }
+ text2send[strlen(text2send) - 1] = '\n';
+ f.data = text2send;
+ f.datalen = strlen(text2send) + 1;
+ grab_owner();
+ if (alsa.owner) {
+ ast_queue_frame(alsa.owner, &f);
+ f.frametype = AST_FRAME_CONTROL;
+ f.subclass = AST_CONTROL_ANSWER;
+ f.data = NULL;
+ f.datalen = 0;
+ ast_queue_frame(alsa.owner, &f);
+ ast_mutex_unlock(&alsa.owner->lock);
+ }
+ }
+
+ ast_mutex_unlock(&alsalock);
+
+ return res;
+}
+
+static char answer_usage[] =
+ "Usage: console answer\n"
+ " Answers an incoming call on the console (ALSA) channel.\n";
+
+static int console_hangup_deprecated(int fd, int argc, char *argv[])
{
int res = RESULT_SUCCESS;
@@ -994,10 +1092,39 @@ static int console_hangup(int fd, int argc, char *argv[])
return res;
}
-static char hangup_usage[] = "Usage: hangup\n" " Hangs up any call currently placed on the console.\n";
+static int console_hangup(int fd, int argc, char *argv[])
+{
+ int res = RESULT_SUCCESS;
+ if (argc != 2)
+ return RESULT_SHOWUSAGE;
-static int console_dial(int fd, int argc, char *argv[])
+ cursound = -1;
+
+ ast_mutex_lock(&alsalock);
+
+ if (!alsa.owner && !hookstate) {
+ ast_cli(fd, "No call to hangup up\n");
+ res = RESULT_FAILURE;
+ } else {
+ hookstate = 0;
+ grab_owner();
+ if (alsa.owner) {
+ ast_queue_hangup(alsa.owner);
+ ast_mutex_unlock(&alsa.owner->lock);
+ }
+ }
+
+ ast_mutex_unlock(&alsalock);
+
+ return res;
+}
+
+static char hangup_usage[] =
+ "Usage: console hangup\n"
+ " Hangs up any call currently placed on the console.\n";
+
+static int console_dial_deprecated(int fd, int argc, char *argv[])
{
char tmp[256], *tmp2;
char *mye, *myc;
@@ -1054,20 +1181,117 @@ static int console_dial(int fd, int argc, char *argv[])
return res;
}
-static char dial_usage[] = "Usage: dial [extension[@context]]\n" " Dials a given extension (and context if specified)\n";
+static int console_dial(int fd, int argc, char *argv[])
+{
+ char tmp[256], *tmp2;
+ char *mye, *myc;
+ char *d;
+ int res = RESULT_SUCCESS;
+
+ if ((argc != 2) && (argc != 3))
+ return RESULT_SHOWUSAGE;
+ ast_mutex_lock(&alsalock);
-static struct ast_cli_entry myclis[] = {
- {{"answer", NULL}, console_answer, "Answer an incoming console call", answer_usage},
- {{"hangup", NULL}, console_hangup, "Hangup a call on the console", hangup_usage},
- {{"dial", NULL}, console_dial, "Dial an extension on the console", dial_usage},
- {{"send", "text", NULL}, console_sendtext, "Send text to the remote device", sendtext_usage},
- {{"autoanswer", NULL}, console_autoanswer, "Sets/displays autoanswer", autoanswer_usage, autoanswer_complete}
+ if (alsa.owner) {
+ if (argc == 3) {
+ d = argv[2];
+ grab_owner();
+ if (alsa.owner) {
+ struct ast_frame f = { AST_FRAME_DTMF };
+ while (*d) {
+ f.subclass = *d;
+ ast_queue_frame(alsa.owner, &f);
+ d++;
+ }
+ ast_mutex_unlock(&alsa.owner->lock);
+ }
+ } else {
+ ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
+ res = RESULT_FAILURE;
+ }
+ } else {
+ mye = exten;
+ myc = context;
+ if (argc == 3) {
+ char *stringp = NULL;
+ strncpy(tmp, argv[2], sizeof(tmp) - 1);
+ stringp = tmp;
+ strsep(&stringp, "@");
+ tmp2 = strsep(&stringp, "@");
+ if (!ast_strlen_zero(tmp))
+ mye = tmp;
+ if (!ast_strlen_zero(tmp2))
+ myc = tmp2;
+ }
+ if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
+ strncpy(alsa.exten, mye, sizeof(alsa.exten) - 1);
+ strncpy(alsa.context, myc, sizeof(alsa.context) - 1);
+ hookstate = 1;
+ alsa_new(&alsa, AST_STATE_RINGING);
+ } else
+ ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
+ }
+
+ ast_mutex_unlock(&alsalock);
+
+ return res;
+}
+
+static char dial_usage[] =
+ "Usage: console dial [extension[@context]]\n"
+ " Dials a given extension (and context if specified)\n";
+
+static struct ast_cli_entry cli_alsa_answer_deprecated = {
+ { "answer", NULL },
+ console_answer_deprecated, NULL,
+ NULL };
+
+static struct ast_cli_entry cli_alsa_hangup_deprecated = {
+ { "hangup", NULL },
+ console_hangup_deprecated, NULL,
+ NULL };
+
+static struct ast_cli_entry cli_alsa_dial_deprecated = {
+ { "dial", NULL },
+ console_dial_deprecated, NULL,
+ NULL };
+
+static struct ast_cli_entry cli_alsa_send_text_deprecated = {
+ { "send", "text", NULL },
+ console_sendtext_deprecated, NULL,
+ NULL };
+
+static struct ast_cli_entry cli_alsa_autoanswer_deprecated = {
+ { "autoanswer", NULL },
+ console_autoanswer_deprecated, NULL,
+ NULL, autoanswer_complete };
+
+static struct ast_cli_entry cli_alsa[] = {
+ { { "console", "answer", NULL },
+ console_answer, "Answer an incoming console call",
+ answer_usage, NULL, &cli_alsa_answer_deprecated },
+
+ { { "console", "hangup", NULL },
+ console_hangup, "Hangup a call on the console",
+ hangup_usage, NULL, &cli_alsa_hangup_deprecated },
+
+ { { "console", "dial", NULL },
+ console_dial, "Dial an extension on the console",
+ dial_usage, NULL, &cli_alsa_dial_deprecated },
+
+ { { "console", "send", "text", NULL },
+ console_sendtext, "Send text to the remote device",
+ sendtext_usage, NULL, &cli_alsa_send_text_deprecated },
+
+ { { "console", "autoanswer", NULL },
+ console_autoanswer, "Sets/displays autoanswer",
+ autoanswer_usage, autoanswer_complete, &cli_alsa_autoanswer_deprecated },
};
static int load_module(void)
{
- int res, x;
+ int res;
struct ast_config *cfg;
struct ast_variable *v;
@@ -1123,8 +1347,8 @@ static int load_module(void)
ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
return -1;
}
- for (x = 0; x < sizeof(myclis) / sizeof(struct ast_cli_entry); x++)
- ast_cli_register(myclis + x);
+ ast_cli_register_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
+
ast_pthread_create(&sthread, NULL, sound_thread, NULL);
#ifdef ALSA_MONITOR
if (alsa_monitor_start())
@@ -1135,11 +1359,9 @@ static int load_module(void)
static int unload_module(void)
{
- int x;
-
ast_channel_unregister(&alsa_tech);
- for (x = 0; x < sizeof(myclis) / sizeof(struct ast_cli_entry); x++)
- ast_cli_unregister(myclis + x);
+ ast_cli_unregister_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry));
+
if (alsa.icard)
snd_pcm_close(alsa.icard);
if (alsa.ocard)