Newer
Older
Josh Roberson
committed
if (!breakon)
Josh Roberson
committed
if (!forward)
Josh Roberson
committed
if (!rewind)
while (c->stream) {
int res;
int ms = ast_sched_wait(c->sched);
if (ms < 0 && !c->timingfunc) {
Mark Spencer
committed
ast_stopstream(c);
if (!cmdfd) {
res = ast_waitfor(c, ms);
if (res < 0) {
ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
return res;
}
} else {
int outfd;
struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
if (!rchan && (outfd < 0) && (ms)) {
/* Continue */
if (errno == EINTR)
continue;
ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
} else if (outfd > -1) { /* this requires cmdfd set */
/* The FD we were watching has something waiting */
return 1;
/* if rchan is set, it is 'c' */
res = rchan ? 1 : 0; /* map into 'res' values */
}
if (res > 0) {
struct ast_frame *fr = ast_read(c);
if (!fr)
return -1;
switch(fr->frametype) {
case AST_FRAME_DTMF:
if (context) {
const char exten[2] = { fr->subclass, '\0' };
if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
ast_frfree(fr);
return res;
}
} else {
res = fr->subclass;
if (strchr(forward,res)) {
ast_stream_fastforward(c->stream, skip_ms);
} else if (strchr(rewind,res)) {
ast_stream_rewind(c->stream, skip_ms);
} else if (strchr(breakon, res)) {
ast_frfree(fr);
return res;
}
}
break;
case AST_FRAME_CONTROL:
switch(fr->subclass) {
case AST_CONTROL_HANGUP:
ast_frfree(fr);
return -1;
case AST_CONTROL_RINGING:
case AST_CONTROL_ANSWER:
/* Unimportant */
break;
default:
ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
}
case AST_FRAME_VOICE:
/* Write audio if appropriate */
if (audiofd > -1)
write(audiofd, fr->data, fr->datalen);
}
/* Ignore all others */
}
return (c->_softhangup ? -1 : 0);
}
Mark Spencer
committed
int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)
{
return waitstream_core(c, breakon, forward, rewind, ms,
-1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
}
int ast_waitstream(struct ast_channel *c, const char *breakon)
{
return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
}
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
{
return waitstream_core(c, breakon, NULL, NULL, 0,
audiofd, cmdfd, NULL /* no context */);
}
Kevin P. Fleming
committed
int ast_waitstream_exten(struct ast_channel *c, const char *context)
{
/* Waitstream, with return in the case of a valid 1 digit extension */
/* in the current or specified context being pressed */
if (!context)
context = c->context;
return waitstream_core(c, NULL, NULL, NULL, 0,
-1, -1, context);
Kevin P. Fleming
committed
}
Mark Spencer
committed
static int show_file_formats(int fd, int argc, char *argv[])
{
#define FORMAT "%-10s %-10s %-20s\n"
#define FORMAT2 "%-10s %-10s %-20s\n"
struct ast_format *f;
Mark Spencer
committed
if (argc != 3)
return RESULT_SHOWUSAGE;
ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
if (AST_LIST_LOCK(&formats)) {
Mark Spencer
committed
ast_log(LOG_WARNING, "Unable to lock format list\n");
return -1;
Mark Spencer
committed
AST_LIST_TRAVERSE(&formats, f, list) {
Mark Spencer
committed
ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
}
AST_LIST_UNLOCK(&formats);
ast_cli(fd, "%d file formats registered.\n", count_fmt);
Mark Spencer
committed
return RESULT_SUCCESS;
#undef FORMAT
#undef FORMAT2
Mark Spencer
committed
}
struct ast_cli_entry show_file =
{
{ "show", "file", "formats" },
show_file_formats,
"Displays file formats",
"Usage: show file formats\n"
" displays currently registered file formats (if any)\n"
};
int ast_file_init(void)
{
ast_cli_register(&show_file);
return 0;
}