📄 chan_alsa.c
字号:
} 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 int console_answer(int fd, int argc, char *argv[]){ int res = RESULT_SUCCESS; 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; 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 { 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 int console_sendtext(int fd, int argc, char *argv[]){ int tmparg = 3; int res = RESULT_SUCCESS; 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; if (argc != 1) return RESULT_SHOWUSAGE; 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 int console_hangup(int fd, int argc, char *argv[]){ int res = RESULT_SUCCESS; if (argc != 2) return RESULT_SHOWUSAGE; 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; char *d; int res = RESULT_SUCCESS; if ((argc != 1) && (argc != 2)) return RESULT_SHOWUSAGE; ast_mutex_lock(&alsalock); if (alsa.owner) { if (argc == 2) { d = argv[1]; 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 == 2) { char *stringp = NULL; ast_copy_string(tmp, argv[1], sizeof(tmp)); 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)) { ast_copy_string(alsa.exten, mye, sizeof(alsa.exten)); ast_copy_string(alsa.context, myc, sizeof(alsa.context)); 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 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); 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; ast_copy_string(tmp, argv[2], sizeof(tmp)); 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)) { ast_copy_string(alsa.exten, mye, sizeof(alsa.exten)); ast_copy_string(alsa.context, myc, sizeof(alsa.context)); 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; struct ast_config *cfg; struct ast_variable *v; /* Copy the default jb config over global_jbconf */ memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); strcpy(mohinterpret, "default"); if ((cfg = ast_config_load(config))) { 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")) autoanswer = ast_true(v->value); else if (!strcasecmp(v->name, "silencesuppression")) silencesuppression = ast_true(v->value); else if (!strcasecmp(v->name, "silencethreshold")) silencethreshold = atoi(v->value); else if (!strcasecmp(v->name, "context")) ast_copy_string(context, v->value, sizeof(context)); else if (!strcasecmp(v->name, "language")) ast_copy_string(language, v->value, sizeof(language)); else if (!strcasecmp(v->name, "extension")) ast_copy_string(exten, v->value, sizeof(exten)); else if (!strcasecmp(v->name, "input_device")) ast_copy_string(indevname, v->value, sizeof(indevname)); else if (!strcasecmp(v->name, "output_device")) ast_copy_string(outdevname, v->value, sizeof(outdevname)); else if (!strcasecmp(v->name, "mohinterpret")) ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); } ast_config_destroy(cfg); } res = pipe(sndcmd); if (res) { ast_log(LOG_ERROR, "Unable to create pipe\n"); return -1; } res = soundcard_init(); if (res < 0) { if (option_verbose > 1) { ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n"); ast_verbose(VERBOSE_PREFIX_2 "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n"); } return 0; } res = ast_channel_register(&alsa_tech); if (res < 0) { ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n"); return -1; } ast_cli_register_multiple(cli_alsa, sizeof(cli_alsa) / sizeof(struct ast_cli_entry)); ast_pthread_create_background(&sthread, NULL, sound_thread, NULL);#ifdef ALSA_MONITOR if (alsa_monitor_start()) ast_log(LOG_ERROR, "Problem starting Monitoring\n");#endif return 0;}static int unload_module(void){ ast_channel_unregister(&alsa_tech); 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) snd_pcm_close(alsa.ocard); if (sndcmd[0] > 0) { close(sndcmd[0]); close(sndcmd[1]); } if (alsa.owner) ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD); if (alsa.owner) return -1; return 0;}AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ALSA Console Channel Driver");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -