📄 chan_oss.c
字号:
return 0;}static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen){ struct chan_oss_pvt *o = c->tech_pvt; int res = -1; switch (cond) { case AST_CONTROL_BUSY: case AST_CONTROL_CONGESTION: case AST_CONTROL_RINGING: res = cond; break; case -1: o->cursound = -1; o->nosound = 0; /* when cursound is -1 nosound must be 0 */ return 0; case AST_CONTROL_VIDUPDATE: res = -1; break; case AST_CONTROL_HOLD: ast_verbose(" << Console Has Been Placed on Hold >> \n"); ast_moh_start(c, data, o->mohinterpret); break; case AST_CONTROL_UNHOLD: ast_verbose(" << Console Has Been Retrieved from Hold >> \n"); ast_moh_stop(c); break; case AST_CONTROL_SRCUPDATE: break; default: ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name); return -1; } if (res > -1) ring(o, res); return 0;}/* * allocate a new channel. */static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, int state){ struct ast_channel *c; c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Console/%s", o->device + 5); if (c == NULL) return NULL; c->tech = &oss_tech; if (o->sounddev < 0) setformat(o, O_RDWR); c->fds[0] = o->sounddev; /* -1 if device closed, override later */ c->nativeformats = AST_FORMAT_SLINEAR; c->readformat = AST_FORMAT_SLINEAR; c->writeformat = AST_FORMAT_SLINEAR; c->tech_pvt = o; if (!ast_strlen_zero(o->language)) ast_string_field_set(c, language, o->language); /* Don't use ast_set_callerid() here because it will * generate a needless NewCallerID event */ c->cid.cid_ani = ast_strdup(o->cid_num); if (!ast_strlen_zero(ext)) c->cid.cid_dnid = ast_strdup(ext); o->owner = c; ast_module_ref(ast_module_info->self); ast_jb_configure(c, &global_jbconf); if (state != AST_STATE_DOWN) { if (ast_pbx_start(c)) { ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name); ast_hangup(c); o->owner = c = NULL; /* XXX what about the channel itself ? */ /* XXX what about usecnt ? */ } } return c;}static struct ast_channel *oss_request(const char *type, int format, void *data, int *cause){ struct ast_channel *c; struct chan_oss_pvt *o = find_desc(data); ast_log(LOG_WARNING, "oss_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data); if (o == NULL) { ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data); /* XXX we could default to 'dsp' perhaps ? */ return NULL; } if ((format & AST_FORMAT_SLINEAR) == 0) { ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format); return NULL; } if (o->owner) { ast_log(LOG_NOTICE, "Already have a call (chan %p) on the OSS channel\n", o->owner); *cause = AST_CAUSE_BUSY; return NULL; } c = oss_new(o, NULL, NULL, AST_STATE_DOWN); if (c == NULL) { ast_log(LOG_WARNING, "Unable to create new OSS channel\n"); return NULL; } return c;}static int console_autoanswer_deprecated(int fd, int argc, char *argv[]){ struct chan_oss_pvt *o = find_desc(oss_active); if (argc == 1) { ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off"); return RESULT_SUCCESS; } if (argc != 2) return RESULT_SHOWUSAGE; if (o == NULL) { ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n", oss_active); return RESULT_FAILURE; } if (!strcasecmp(argv[1], "on")) o->autoanswer = -1; else if (!strcasecmp(argv[1], "off")) o->autoanswer = 0; else return RESULT_SHOWUSAGE; return RESULT_SUCCESS;}static int console_autoanswer(int fd, int argc, char *argv[]){ struct chan_oss_pvt *o = find_desc(oss_active); if (argc == 2) { ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off"); return RESULT_SUCCESS; } if (argc != 3) return RESULT_SHOWUSAGE; if (o == NULL) { ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n", oss_active); return RESULT_FAILURE; } if (!strcasecmp(argv[2], "on")) o->autoanswer = -1; else if (!strcasecmp(argv[2], "off")) o->autoanswer = 0; else return RESULT_SHOWUSAGE; return RESULT_SUCCESS;}static char *autoanswer_complete_deprecated(const char *line, const char *word, int pos, int state){ static char *choices[] = { "on", "off", NULL }; return (pos != 2) ? NULL : ast_cli_complete(word, choices, state);}static char *autoanswer_complete(const char *line, const char *word, int pos, int state){ static char *choices[] = { "on", "off", NULL }; return (pos != 3) ? NULL : ast_cli_complete(word, choices, state);}static char autoanswer_usage[] = "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 'oss.conf'.\n";/* * answer command from the console */static int console_answer_deprecated(int fd, int argc, char *argv[]){ struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 1) return RESULT_SHOWUSAGE; if (!o->owner) { ast_cli(fd, "No one is calling us\n"); return RESULT_FAILURE; } o->hookstate = 1; o->cursound = -1; o->nosound = 0; ast_queue_frame(o->owner, &f);#if 0 /* XXX do we really need it ? considering we shut down immediately... */ ring(o, AST_CONTROL_ANSWER);#endif return RESULT_SUCCESS;}static int console_answer(int fd, int argc, char *argv[]){ struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 2) return RESULT_SHOWUSAGE; if (!o->owner) { ast_cli(fd, "No one is calling us\n"); return RESULT_FAILURE; } o->hookstate = 1; o->cursound = -1; o->nosound = 0; ast_queue_frame(o->owner, &f);#if 0 /* XXX do we really need it ? considering we shut down immediately... */ ring(o, AST_CONTROL_ANSWER);#endif return RESULT_SUCCESS;}static char answer_usage[] = "Usage: console answer\n" " Answers an incoming call on the console (OSS) channel.\n";/* * concatenate all arguments into a single string. argv is NULL-terminated * so we can use it right away */static int console_sendtext_deprecated(int fd, int argc, char *argv[]){ struct chan_oss_pvt *o = find_desc(oss_active); char buf[TEXT_SIZE]; if (argc < 2) return RESULT_SHOWUSAGE; if (!o->owner) { ast_cli(fd, "Not in a call\n"); return RESULT_FAILURE; } ast_join(buf, sizeof(buf) - 1, argv + 2); if (!ast_strlen_zero(buf)) { struct ast_frame f = { 0, }; int i = strlen(buf); buf[i] = '\n'; f.frametype = AST_FRAME_TEXT; f.subclass = 0; f.data = buf; f.datalen = i + 1; ast_queue_frame(o->owner, &f); } return RESULT_SUCCESS;}static int console_sendtext(int fd, int argc, char *argv[]){ struct chan_oss_pvt *o = find_desc(oss_active); char buf[TEXT_SIZE]; if (argc < 3) return RESULT_SHOWUSAGE; if (!o->owner) { ast_cli(fd, "Not in a call\n"); return RESULT_FAILURE; } ast_join(buf, sizeof(buf) - 1, argv + 3); if (!ast_strlen_zero(buf)) { struct ast_frame f = { 0, }; int i = strlen(buf); buf[i] = '\n'; f.frametype = AST_FRAME_TEXT; f.subclass = 0; f.data = buf; f.datalen = i + 1; ast_queue_frame(o->owner, &f); } 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_hangup_deprecated(int fd, int argc, char *argv[]){ struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 1) return RESULT_SHOWUSAGE; o->cursound = -1; o->nosound = 0; if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */ ast_cli(fd, "No call to hang up\n"); return RESULT_FAILURE; } o->hookstate = 0; if (o->owner) ast_queue_hangup(o->owner); setformat(o, O_CLOSE); return RESULT_SUCCESS;}static int console_hangup(int fd, int argc, char *argv[]){ struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 2) return RESULT_SHOWUSAGE; o->cursound = -1; o->nosound = 0; if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */ ast_cli(fd, "No call to hang up\n"); return RESULT_FAILURE; } o->hookstate = 0; if (o->owner) ast_queue_hangup(o->owner); setformat(o, O_CLOSE); return RESULT_SUCCESS;}static char hangup_usage[] = "Usage: console hangup\n" " Hangs up any call currently placed on the console.\n";static int console_flash_deprecated(int fd, int argc, char *argv[]){ struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH }; struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 1) return RESULT_SHOWUSAGE; o->cursound = -1; o->nosound = 0; /* when cursound is -1 nosound must be 0 */ if (!o->owner) { /* XXX maybe !o->hookstate too ? */ ast_cli(fd, "No call to flash\n"); return RESULT_FAILURE; } o->hookstate = 0; if (o->owner) /* XXX must be true, right ? */ ast_queue_frame(o->owner, &f); return RESULT_SUCCESS;}static int console_flash(int fd, int argc, char *argv[]){ struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH }; struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 2) return RESULT_SHOWUSAGE; o->cursound = -1; o->nosound = 0; /* when cursound is -1 nosound must be 0 */ if (!o->owner) { /* XXX maybe !o->hookstate too ? */ ast_cli(fd, "No call to flash\n"); return RESULT_FAILURE; } o->hookstate = 0; if (o->owner) /* XXX must be true, right ? */ ast_queue_frame(o->owner, &f); return RESULT_SUCCESS;}static char flash_usage[] = "Usage: console flash\n" " Flashes the call currently placed on the console.\n";static int console_dial_deprecated(int fd, int argc, char *argv[]){ char *s = NULL, *mye = NULL, *myc = NULL; struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 1 && argc != 2) return RESULT_SHOWUSAGE; if (o->owner) { /* already in a call */ int i; struct ast_frame f = { AST_FRAME_DTMF, 0 }; if (argc == 1) { /* argument is mandatory here */ ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n"); return RESULT_FAILURE; } s = argv[1]; /* send the string one char at a time */ for (i = 0; i < strlen(s); i++) { f.subclass = s[i]; ast_queue_frame(o->owner, &f); } return RESULT_SUCCESS; } /* if we have an argument split it into extension and context */ if (argc == 2) s = ast_ext_ctx(argv[1], &mye, &myc); /* supply default values if needed */ if (mye == NULL) mye = o->ext; if (myc == NULL) myc = o->ctx; if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { o->hookstate = 1; oss_new(o, mye, myc, AST_STATE_RINGING); } else ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc); if (s) free(s); return RESULT_SUCCESS;}static int console_dial(int fd, int argc, char *argv[]){ char *s = NULL, *mye = NULL, *myc = NULL; struct chan_oss_pvt *o = find_desc(oss_active); if (argc != 2 && argc != 3) return RESULT_SHOWUSAGE; if (o->owner) { /* already in a call */ int i; struct ast_frame f = { AST_FRAME_DTMF, 0 }; if (argc == 2) { /* argument is mandatory here */ ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n"); return RESULT_FAILURE; } s = argv[2]; /* send the string one char at a time */ for (i = 0; i < strlen(s); i++) { f.subclass = s[i]; ast_queue_frame(o->owner, &f); } return RESULT_SUCCESS; } /* if we have an argument split it into extension and context */ if (argc == 3) s = ast_ext_ctx(argv[2], &mye, &myc); /* supply default values if needed */ if (mye == NULL) mye = o->ext; if (myc == NULL) myc = o->ctx; if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { o->hookstate = 1; oss_new(o, mye, myc, AST_STATE_RINGING); } else ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc); if (s) free(s); return RESULT_SUCCESS;}static char dial_usage[] = "Usage: console dial [extension[@context]]\n" " Dials a given extension (and context if specified)\n";static int __console_mute_unmute(int mute){ struct chan_oss_pvt *o = find_desc(oss_active); o->mute = mute; return RESULT_SUCCESS;}static int console_mute_deprecated(int fd, int argc, char *argv[]){ if (argc != 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -