Skip to content
Snippets Groups Projects
file.c 32.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    			if (!fr) {
    #if 0
    				ast_log(LOG_DEBUG, "Got hung up\n");
    #endif
    				return -1;
    			}
    			
    			switch(fr->frametype) {
    			case AST_FRAME_DTMF:
    				res = fr->subclass;
    
    Mark Spencer's avatar
    Mark Spencer committed
    				if (strchr(breakon, res)) {
    					ast_frfree(fr);
    
    Mark Spencer's avatar
    Mark Spencer committed
    					return res;
    
    Mark Spencer's avatar
    Mark Spencer committed
    				break;
    			case AST_FRAME_CONTROL:
    				switch(fr->subclass) {
    				case AST_CONTROL_HANGUP:
    					ast_frfree(fr);
    					return -1;
    
    Mark Spencer's avatar
    Mark Spencer committed
    				case AST_CONTROL_RINGING:
    				case AST_CONTROL_ANSWER:
    
    Mark Spencer's avatar
    Mark Spencer committed
    				case AST_CONTROL_VIDUPDATE:
    
    Mark Spencer's avatar
    Mark Spencer committed
    					/* Unimportant */
    					break;
    
    Mark Spencer's avatar
    Mark Spencer committed
    				default:
    					ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
    				}
    			}
    
    Mark Spencer's avatar
    Mark Spencer committed
    			/* Ignore */
    			ast_frfree(fr);
    
    		}
    		ast_sched_runq(c->sched);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	return (c->_softhangup ? -1 : 0);
    
    int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)
    
    {
    	int res;
    	struct ast_frame *fr;
    
    
    	if (!breakon)
    			breakon = "";
    	if (!forward)
    			forward = "";
    	if (!rewind)
    			rewind = "";
    	
    
    	while(c->stream) {
    		res = ast_sched_wait(c->sched);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if ((res < 0) && !c->timingfunc) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if (res < 0)
    			res = 1000;
    
    		res = ast_waitfor(c, res);
    		if (res < 0) {
    			ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
    			return res;
    		} else
    		if (res > 0) {
    			fr = ast_read(c);
    			if (!fr) {
    #if 0
    				ast_log(LOG_DEBUG, "Got hung up\n");
    #endif
    				return -1;
    			}
    			
    			switch(fr->frametype) {
    			case AST_FRAME_DTMF:
    				res = fr->subclass;
    				if (strchr(forward,res)) {
    
    					ast_stream_fastforward(c->stream, ms);
    
    				} else if (strchr(rewind,res)) {
    
    					ast_stream_rewind(c->stream, 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);
    				}
    			}
    			/* Ignore */
    			ast_frfree(fr);
    		} else
    			ast_sched_runq(c->sched);
    	
    		
    	}
    	return (c->_softhangup ? -1 : 0);
    }
    
    
    int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
    
    {
    	int res;
    	int ms;
    	int outfd;
    	struct ast_frame *fr;
    	struct ast_channel *rchan;
    
    	
    	while(c->stream) {
    		ms = ast_sched_wait(c->sched);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if ((ms < 0) && !c->timingfunc) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if (ms < 0)
    			ms = 1000;
    
    		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) {
    			/* The FD we were watching has something waiting */
    			return 1;
    		} else if (rchan) {
    			fr = ast_read(c);
    			if (!fr) {
    #if 0
    				ast_log(LOG_DEBUG, "Got hung up\n");
    #endif
    				return -1;
    			}
    			
    			switch(fr->frametype) {
    			case AST_FRAME_DTMF:
    				res = fr->subclass;
    				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 */
    			ast_frfree(fr);
    
    		}
    		ast_sched_runq(c->sched);
    
    	}
    	return (c->_softhangup ? -1 : 0);
    }
    
    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 */
    	/* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
    	int res;
    	struct ast_frame *fr;
    
    	char exten[AST_MAX_EXTENSION];
    
    
    	if (!context) context = c->context;
    	while(c->stream) {
    		res = ast_sched_wait(c->sched);
    		if ((res < 0) && !c->timingfunc) {
    			ast_stopstream(c);
    			break;
    		}
    		if (res < 0)
    			res = 1000;
    		res = ast_waitfor(c, res);
    		if (res < 0) {
    			ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
    			return res;
    		} else if (res > 0) {
    			fr = ast_read(c);
    			if (!fr) {
    #if 0
    				ast_log(LOG_DEBUG, "Got hung up\n");
    #endif
    				return -1;
    			}
    			
    			switch(fr->frametype) {
    			case AST_FRAME_DTMF:
    				res = fr->subclass;
    				snprintf(exten, sizeof(exten), "%c", res);
    				if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
    					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);
    				}
    			}
    			/* Ignore */
    			ast_frfree(fr);
    		}
    		ast_sched_runq(c->sched);
    	}
    	return (c->_softhangup ? -1 : 0);
    }
    
    
    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_mutex_lock(&formatlock)) {
    		ast_log(LOG_WARNING, "Unable to lock format list\n");
    		return -1;
    
    James Golovich's avatar
    James Golovich committed
    	}
    
    
    	f = formats;
    	while(f) {
    		ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
    		f = f->next;
    
    	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;
    }