Skip to content
Snippets Groups Projects
pbx.c 113 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    	res = ast_streamfile(chan, (char *)data, chan->language);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (!res) {
    		res = ast_waitstream(chan, AST_DIGIT_ANY);
    		ast_stopstream(chan);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	return res;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static int pbx_builtin_atimeout(struct ast_channel *chan, void *data)
    {
    	int x = atoi((char *) data);
    	/* Set the timeout for how long to wait between digits */
    	ast_channel_setwhentohangup(chan,x);
    	if (option_verbose > 2)
    		ast_verbose( VERBOSE_PREFIX_3 "Set Absolute Timeout to %d\n", x);
    	return 0;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static int pbx_builtin_rtimeout(struct ast_channel *chan, void *data)
    
    Mark Spencer's avatar
    Mark Spencer committed
    {
    	/* Set the timeout for how long to wait between digits */
    	chan->pbx->rtimeout = atoi((char *)data);
    	if (option_verbose > 2)
    		ast_verbose( VERBOSE_PREFIX_3 "Set Response Timeout to %d\n", chan->pbx->rtimeout);
    	return 0;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static int pbx_builtin_dtimeout(struct ast_channel *chan, void *data)
    
    Mark Spencer's avatar
    Mark Spencer committed
    {
    	/* Set the timeout for how long to wait between digits */
    	chan->pbx->dtimeout = atoi((char *)data);
    	if (option_verbose > 2)
    		ast_verbose( VERBOSE_PREFIX_3 "Set Digit Timeout to %d\n", chan->pbx->dtimeout);
    	return 0;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static int pbx_builtin_goto(struct ast_channel *chan, void *data)
    
    Mark Spencer's avatar
    Mark Spencer committed
    {
    	char *s;
    	char *exten, *pri, *context;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char *stringp=NULL;
    	if (!data || !strlen(data)) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_log(LOG_WARNING, "Goto requires an argument (optional context|optional extension|priority)\n");
    		return -1;
    	}
    	s = strdup((void *) data);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	stringp=s;
    	context = strsep(&stringp, "|");
    	exten = strsep(&stringp, "|");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (!exten) {
    		/* Only a priority in this one */
    		pri = context;
    		exten = NULL;
    		context = NULL;
    	} else {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		pri = strsep(&stringp, "|");
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if (!pri) {
    			/* Only an extension and priority in this one */
    			pri = exten;
    			exten = context;
    			context = NULL;
    		}
    	}
    	if (atoi(pri) < 0) {
    		ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", pri);
    		free(s);
    		return -1;
    	}
    	/* At this point we have a priority and maybe an extension and a context */
    	chan->priority = atoi(pri) - 1;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (exten && strcasecmp(exten, "BYEXTENSION"))
    
    Mark Spencer's avatar
    Mark Spencer committed
    		strncpy(chan->exten, exten, sizeof(chan->exten)-1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (context)
    
    Mark Spencer's avatar
    Mark Spencer committed
    		strncpy(chan->context, context, sizeof(chan->context)-1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (option_verbose > 2)
    		ast_verbose( VERBOSE_PREFIX_3 "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
    	return 0;
    }
    
    Mark Spencer's avatar
    Mark Spencer committed
    char *pbx_builtin_getvar_helper(struct ast_channel *chan, char *name) {
    	struct ast_var_t *variables;
    	struct varshead *headp;
    
    
        if (chan)
            headp=&chan->varshead;
    	else
    		headp=&globals;
    
    	if (name) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		AST_LIST_TRAVERSE(headp,variables,entries) {
    			if (!strcmp(name, ast_var_name(variables)))
    				return ast_var_value(variables);
    		}
    
    		if (headp != &globals) {
    			/* Check global variables if we haven't already */
    			headp = &globals;
    			AST_LIST_TRAVERSE(headp,variables,entries) {
    				if (!strcmp(name, ast_var_name(variables)))
    					return ast_var_value(variables);
    			}
    		}
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	return NULL;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value) {
    	struct ast_var_t *newvariable;
            struct varshead *headp;
    
        if (chan)
    
    Mark Spencer's avatar
    Mark Spencer committed
            headp=&chan->varshead;
    
    	else
    		headp=&globals;
    
    Mark Spencer's avatar
    Mark Spencer committed
                    
    	AST_LIST_TRAVERSE (headp,newvariable,entries) {
    
    		if (strcasecmp(ast_var_name(newvariable),name)==0) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    			/* there is already such a variable, delete it */
    			AST_LIST_REMOVE(headp,newvariable,ast_var_t,entries);
    			ast_var_delete(newvariable);
    			break;
    		}
    	} 
    	
    
    	if (value) {
    		if ((option_verbose > 1) && (headp == &globals))
    			ast_verbose(VERBOSE_PREFIX_3 "Setting global variable '%s' to '%s'\n",name, value);
    		newvariable=ast_var_assign(name,value);	
    		AST_LIST_INSERT_HEAD(headp,newvariable,entries);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    }
    
    static int pbx_builtin_setvar(struct ast_channel *chan, void *data)
    {
    	char *name;
    	char *value;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char *stringp=NULL;
    
    Mark Spencer's avatar
    Mark Spencer committed
                    
    	if (!data || !strlen(data)) {
    		ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
    		return 0;
    	}
    	
    
    Mark Spencer's avatar
    Mark Spencer committed
    	stringp=data;
    	name=strsep(&stringp,"=");
    	value=strsep(&stringp,"\0"); 
    
    Mark Spencer's avatar
    Mark Spencer committed
    	
    	pbx_builtin_setvar_helper(chan,name,value);
    			
            return(0);
    }
    
    
    static int pbx_builtin_setglobalvar(struct ast_channel *chan, void *data)
    {
    	char *name;
    	char *value;
    	char *stringp=NULL;
                    
    	if (!data || !strlen(data)) {
    		ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
    		return 0;
    	}
    	
    	stringp=data;
    	name=strsep(&stringp,"=");
    	value=strsep(&stringp,"\0"); 
    	
    	pbx_builtin_setvar_helper(NULL,name,value);
    			
            return(0);
    }
    
    
    
    static int pbx_builtin_noop(struct ast_channel *chan, void *data)
    {
    	return 0;
    }
    
    
    void pbx_builtin_clear_globals(void)
    {
    	struct ast_var_t *vardata;
    	while (!AST_LIST_EMPTY(&globals)) {
    		vardata = AST_LIST_FIRST(&globals);
    		AST_LIST_REMOVE_HEAD(&globals, entries);
    		ast_var_delete(vardata);
    	}
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static int pbx_checkcondition(char *condition) {
    	char *s;
    	int ret;
    	
    	s=strdup(condition);
    	
    	ret=1;
    	
    	if ((strcasecmp(s,"0")) || (strlen(s)==0)) {
    		ret=0;
    	}
    	
    	free(s);
    	return(ret);
    }
    
    static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
    {
    	char *condition,*branch1,*branch2,*branch;
    	char *s;
    	int rc;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char *stringp=NULL;
    
    Mark Spencer's avatar
    Mark Spencer committed
    
    	if (!data || !strlen(data)) {
    		ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
    		return 0;
    	}
    	
    	s=strdup(data);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	stringp=s;
    	condition=strsep(&stringp,"?");
    	branch1=strsep(&stringp,":");
    	branch2=strsep(&stringp,"");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	
    	if (pbx_checkcondition(condition)) {
    		branch=branch2;
    	} else {
    		branch=branch1;
    	}
    	
    	if ((branch==NULL) || (strlen(branch)==0)) {
    		ast_log(LOG_WARNING, "Not taking any branch\n");
    		return(0);
    	}
    	
    	rc=pbx_builtin_goto(chan,branch);
    	free(s);
    	return(rc);
    }           
    
    Mark Spencer's avatar
    Mark Spencer committed
    
    static int pbx_builtin_saynumber(struct ast_channel *chan, void *data)
    {
    	int res = 0;
    	if (data && atoi((char *)data) )
    		res = ast_say_number(chan, atoi((char *)data), "", chan->language);
    	return res;
    }
    
    static int pbx_builtin_saydigits(struct ast_channel *chan, void *data)
    {
    	int res = 0;
    	if (data && atoi((char *)data))
    		res = ast_say_digits(chan, atoi((char *)data), "", chan->language);
    	return res;
    }
    
    Mark Spencer's avatar
    Mark Spencer committed
    int load_pbx(void)
    {
    	int x;
    	/* Initialize the PBX */
    	if (option_verbose) {
    		ast_verbose( "Asterisk PBX Core Initializing\n");
    		ast_verbose( "Registering builtin applications:\n");
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	ast_cli_register(&show_applications_cli);
    	ast_cli_register(&show_application_cli);
    	ast_cli_register(&show_dialplan_cli);
    	ast_cli_register(&show_switches_cli);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	for (x=0;x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) {
    		if (option_verbose)
    			ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    			ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
    			return -1;
    		}
    	}
    	return 0;
    }
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    /*
     * Lock context list functions ...
     */
    int ast_lock_contexts()
    {
    	return ast_pthread_mutex_lock(&conlock);
    }
    
    int ast_unlock_contexts()
    {
    	return ast_pthread_mutex_unlock(&conlock);
    }
    
    /*
     * Lock context ...
     */
    int ast_lock_context(struct ast_context *con)
    {
    	return ast_pthread_mutex_lock(&con->lock);
    }
    
    int ast_unlock_context(struct ast_context *con)
    {
    	return ast_pthread_mutex_unlock(&con->lock);
    }
    
    /*
     * Name functions ...
     */
    char *ast_get_context_name(struct ast_context *con)
    {
    	return con ? con->name : NULL;
    }
    
    char *ast_get_extension_name(struct ast_exten *exten)
    {
    	return exten ? exten->exten : NULL;
    }
    
    char *ast_get_include_name(struct ast_include *inc)
    {
    	return inc ? inc->name : NULL;
    }
    
    char *ast_get_ignorepat_name(struct ast_ignorepat *ip)
    {
    	return ip ? ip->pattern : NULL;
    }
    
    int ast_get_extension_priority(struct ast_exten *exten)
    {
    	return exten ? exten->priority : -1;
    }
    
    /*
     * Registrar info functions ...
     */
    char *ast_get_context_registrar(struct ast_context *c)
    {
    	return c ? c->registrar : NULL;
    }
    
    char *ast_get_extension_registrar(struct ast_exten *e)
    {
    	return e ? e->registrar : NULL;
    }
    
    char *ast_get_include_registrar(struct ast_include *i)
    {
    	return i ? i->registrar : NULL;
    }
    
    char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip)
    {
    	return ip ? ip->registrar : NULL;
    }
    
    char *ast_get_extension_app(struct ast_exten *e)
    {
    	return e ? e->app : NULL;
    }
    
    void *ast_get_extension_app_data(struct ast_exten *e)
    {
    	return e ? e->data : NULL;
    }
    
    char *ast_get_switch_name(struct ast_sw *sw)
    {
    	return sw ? sw->name : NULL;
    }
    
    char *ast_get_switch_data(struct ast_sw *sw)
    {
    	return sw ? sw->data : NULL;
    }
    
    char *ast_get_switch_registrar(struct ast_sw *sw)
    {
    	return sw ? sw->registrar : NULL;
    }
    
    /*
     * Walking functions ...
     */
    struct ast_context *ast_walk_contexts(struct ast_context *con)
    {
    	if (!con)
    		return contexts;
    	else
    		return con->next;
    }
    
    struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
    	struct ast_exten *exten)
    {
    	if (!exten)
    		return con ? con->root : NULL;
    	else
    		return exten->next;
    }
    
    struct ast_sw *ast_walk_context_switches(struct ast_context *con,
    	struct ast_sw *sw)
    {
    	if (!sw)
    		return con ? con->alts : NULL;
    	else
    		return sw->next;
    }
    
    struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
    	struct ast_exten *priority)
    {
    	if (!priority)
    		return exten;
    	else
    		return priority->peer;
    }
    
    struct ast_include *ast_walk_context_includes(struct ast_context *con,
    	struct ast_include *inc)
    {
    	if (!inc)
    		return con ? con->includes : NULL;
    	else
    		return inc->next;
    }
    
    struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
    	struct ast_ignorepat *ip)
    {
    	if (!ip)
    		return con ? con->ignorepats : NULL;
    	else
    		return ip->next;
    }