Skip to content
Snippets Groups Projects
file.c 30.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    		if (ms < 0)
    			ms = 1000;
    
    		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));
    
    				return -1;
    
    			} 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:
    
    				case AST_CONTROL_VIDUPDATE:
    
    					/* 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 */
    
    			ast_frfree(fr);
    
    		}
    		ast_sched_runq(c->sched);
    
    	}
    	return (c->_softhangup ? -1 : 0);
    }
    
    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 */);
    }
    
    
    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);
    
    /*
     * if the file name is non-empty, try to play it.
     * Return 0 if success, -1 if error, digit if interrupted by a digit.
     * If digits == "" then we can simply check for non-zero.
     */
    int ast_stream_and_wait(struct ast_channel *chan, const char *file,
    	const char *language, const char *digits)
    {
            int res = 0;
            if (!ast_strlen_zero(file)) {
                    res =  ast_streamfile(chan, file, language);
                    if (!res)
                            res = ast_waitstream(chan, digits);
            }
            return res;
    } 
    
    
    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;
    
    	if (argc != 3)
    		return RESULT_SHOWUSAGE;
    	ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
    	        
    
    	if (AST_LIST_LOCK(&formats)) {
    
    		ast_log(LOG_WARNING, "Unable to lock format list\n");
    		return -1;
    
    James Golovich's avatar
    James Golovich committed
    	}
    
    	AST_LIST_TRAVERSE(&formats, f, list) {
    
    		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);
    
    }
    
    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;
    }