Newer
Older
if (!app || ast_strlen_zero(app))
chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
if (account)
ast_cdr_setaccount(chan, account);
if(chan->cdr) { /* check if the channel already has a cdr record, if not give it one */
ast_log(LOG_WARNING, "%s already has a call record??\n", chan->name);
} else {
chan->cdr = ast_cdr_alloc(); /* allocate a cdr for the channel */
if(!chan->cdr) {
/* allocation of the cdr failed */
ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
free(chan->pbx);
return -1; /* return failure */
}
/* allocation of the cdr was successful */
ast_cdr_init(chan->cdr, chan); /* initilize our channel's cdr */
ast_cdr_start(chan->cdr);
}
if (variable) {
vartmp = ast_strdupa(variable);
for (var = strtok_r(vartmp, "|", &vartmp); var; var = strtok_r(NULL, "|", &vartmp)) {
pbx_builtin_setvar( chan, var );
}
if (chan->_state == AST_STATE_UP) {
res = 0;
if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", chan->name);
tmp = malloc(sizeof(struct app_tmp));
if (tmp) {
memset(tmp, 0, sizeof(struct app_tmp));
ast_copy_string(tmp->app, app, sizeof(tmp->app));
if (appdata)
ast_copy_string(tmp->data, appdata, sizeof(tmp->data));
if (locked_channel)
ast_mutex_unlock(&chan->lock);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (locked_channel)
ast_mutex_lock(&chan->lock);
if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", chan->name, strerror(errno));
free(tmp);
if (locked_channel)
ast_mutex_unlock(&chan->lock);
} else {
if (locked_channel)
*locked_channel = chan;
ast_log(LOG_ERROR, "Out of memory :(\n");
res = -1;
}
} else {
if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", chan->name);
if(chan->cdr) { /* update the cdr */
/* here we update the status of the call, which sould be busy.
* if that fails then we set the status to failed */
if(ast_cdr_disposition(chan->cdr, chan->hangupcause))
ast_cdr_failed(chan->cdr);
}
if(res < 0) { /* the call failed for some reason */
if(*reason == 0) { /* if the call failed (not busy or no answer)
* update the cdr with the failed message */
cdr_res = ast_pbx_outgoing_cdr_failed();
if(cdr_res != 0)
return cdr_res;
}
}
} else {
as = malloc(sizeof(struct async_stat));
if (!as)
return -1;
memset(as, 0, sizeof(struct async_stat));
chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name);
if (!chan) {
free(as);
return -1;
}
if (account)
ast_cdr_setaccount(chan, account);
ast_copy_string(as->app, app, sizeof(as->app));
ast_copy_string(as->appdata, appdata, sizeof(as->appdata));
vartmp = ast_strdupa(variable);
for (var = strtok_r(vartmp, "|", &vartmp); var; var = strtok_r(NULL, "|", &vartmp))
pbx_builtin_setvar( chan, var );
/* Start a new thread, and get something handling this channel. */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (locked_channel)
ast_mutex_lock(&chan->lock);
if (ast_pthread_create(&as->p, &attr, async_wait, as)) {
ast_log(LOG_WARNING, "Failed to start async wait\n");
free(as);
if (locked_channel)
ast_mutex_unlock(&chan->lock);
} else {
if (locked_channel)
*locked_channel = chan;
}
res = 0;
}
return res;
}
static void destroy_exten(struct ast_exten *e)
{
if (e->priority == PRIORITY_HINT)
ast_remove_hint(e);
if (e->datad)
e->datad(e->data);
free(e);
}
void __ast_context_destroy(struct ast_context *con, const char *registrar)
struct ast_exten *e, *el, *en;
Mark Spencer
committed
ast_mutex_lock(&conlock);
if (((tmp->name && con && con->name && !strcasecmp(tmp->name, con->name)) || !con) &&
(!registrar || !strcasecmp(registrar, tmp->registrar))) {
/* Okay, let's lock the structure to be sure nobody else
is searching through it. */
if (ast_mutex_lock(&tmp->lock)) {
ast_log(LOG_WARNING, "Unable to lock context lock\n");
return;
}
if (tmpl)
tmpl->next = tmp->next;
else
contexts = tmp->next;
/* Okay, now we're safe to let it go -- in a sense, we were
ready to let it go as soon as we locked it. */
ast_mutex_unlock(&tmp->lock);
for (tmpi = tmp->includes; tmpi; ) {
/* Free includes */
tmpil = tmpi;
tmpi = tmpi->next;
free(tmpil);
ipl = ipi;
ipi = ipi->next;
free(ipl);
swl = sw;
sw = sw->next;
free(swl);
swl = sw;
}
for (e = tmp->root; e;) {
for (en = e->peer; en;) {
el = en;
en = en->peer;
destroy_exten(el);
}
el = e;
e = e->next;
destroy_exten(el);
}
ast_mutex_destroy(&tmp->lock);
if (!con) {
/* Might need to get another one -- restart */
tmp = contexts;
tmpl = NULL;
tmpil = NULL;
continue;
}
Mark Spencer
committed
ast_mutex_unlock(&conlock);
return;
}
tmpl = tmp;
tmp = tmp->next;
}
Mark Spencer
committed
ast_mutex_unlock(&conlock);
void ast_context_destroy(struct ast_context *con, const char *registrar)
Mark Spencer
committed
__ast_context_destroy(con,registrar);
static void wait_for_hangup(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
if (!data || !strlen(data) || (sscanf(data, "%d", &waittime) != 1) || (waittime < 0))
waittime = -1;
if (waittime > -1) {
ast_safe_sleep(chan, waittime * 1000);
} else do {
res = ast_waitfor(chan, -1);
if (res < 0)
return;
f = ast_read(chan);
if (f)
ast_frfree(f);
} while(f);
}
static int pbx_builtin_progress(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_PROGRESS);
return 0;
}
static int pbx_builtin_ringing(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_RINGING);
return 0;
}
static int pbx_builtin_busy(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_BUSY);
wait_for_hangup(chan, data);
return -1;
}
static int pbx_builtin_congestion(struct ast_channel *chan, void *data)
{
ast_indicate(chan, AST_CONTROL_CONGESTION);
wait_for_hangup(chan, data);
return -1;
}
static int pbx_builtin_answer(struct ast_channel *chan, void *data)
int delay = atoi(data);
int res;
if (chan->_state == AST_STATE_UP)
delay = 0;
res = ast_answer(chan);
if (res)
return res;
if (delay)
res = ast_safe_sleep(chan, delay);
return res;
static int pbx_builtin_setlanguage(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
static int deprecation_warning = 0;
if (!deprecation_warning) {
ast_log(LOG_WARNING, "SetLanguage is deprecated, please use Set(LANGUAGE()=language) instead.\n");
Kevin P. Fleming
committed
deprecation_warning = 1;
}
James Golovich
committed
if (data)
ast_copy_string(chan->language, (char *) data, sizeof(chan->language));
Kevin P. Fleming
committed
static int pbx_builtin_resetcdr(struct ast_channel *chan, void *data)
{
/* Reset the CDR as specified */
if(data) {
if(strchr((char *)data, 'w'))
flags |= AST_CDR_FLAG_POSTED;
if(strchr((char *)data, 'a'))
flags |= AST_CDR_FLAG_LOCKED;
if(strchr((char *)data, 'v'))
flags |= AST_CDR_FLAG_KEEP_VARS;
Mark Spencer
committed
static int pbx_builtin_setaccount(struct ast_channel *chan, void *data)
{
/* Copy the account code as specified */
Mark Spencer
committed
if (data)
ast_cdr_setaccount(chan, (char *)data);
else
ast_cdr_setaccount(chan, "");
return 0;
}
static int pbx_builtin_setamaflags(struct ast_channel *chan, void *data)
{
/* Copy the AMA Flags as specified */
if (data)
ast_cdr_setamaflags(chan, (char *)data);
else
ast_cdr_setamaflags(chan, "");
return 0;
}
static int pbx_builtin_hangup(struct ast_channel *chan, void *data)
{
/* Just return non-zero and it will hang up */
return -1;
}
static int pbx_builtin_stripmsd(struct ast_channel *chan, void *data)
if (!data || !atoi(data)) {
ast_log(LOG_DEBUG, "Ignoring, since number of digits to strip is 0\n");
return 0;
}
if (strlen(chan->exten) > atoi(data)) {
ast_copy_string(newexten, chan->exten + atoi(data), sizeof(newexten));
ast_copy_string(chan->exten, newexten, sizeof(chan->exten));
static int pbx_builtin_prefix(struct ast_channel *chan, void *data)
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_DEBUG, "Ignoring, since there is no prefix to add\n");
return 0;
}
snprintf(newexten, sizeof(newexten), "%s%s", (char *)data, chan->exten);
ast_copy_string(chan->exten, newexten, sizeof(chan->exten));
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Prepended prefix, new extension is %s\n", chan->exten);
static int pbx_builtin_suffix(struct ast_channel *chan, void *data)
{
char newexten[AST_MAX_EXTENSION] = "";
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_DEBUG, "Ignoring, since there is no suffix to add\n");
return 0;
}
snprintf(newexten, sizeof(newexten), "%s%s", chan->exten, (char *)data);
ast_copy_string(chan->exten, newexten, sizeof(chan->exten));
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Appended suffix, new extension is %s\n", chan->exten);
return 0;
}
static int pbx_builtin_gotoiftime(struct ast_channel *chan, void *data)
{
int res=0;
char *s, *ts;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?[[context|]extension|]priority\n");
return -1;
}
if ((s = ast_strdupa((char *) data))) {
ts = s;
/* Separate the Goto path */
strsep(&ts,"?");
/* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
if (ast_build_timing(&timing, s) && ast_check_timing(&timing))
res = pbx_builtin_goto(chan, (void *)ts);
} else {
ast_log(LOG_ERROR, "Memory Error!\n");
}
return res;
}
static int pbx_builtin_execiftime(struct ast_channel *chan, void *data)
{
int res = 0;
char *ptr1, *ptr2;
struct ast_timing timing;
const char *usage = "ExecIfTime requires an argument:\n <time range>|<days of week>|<days of month>|<months>?<appname>[|<appargs>]";
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "%s\n", usage);
if ((ptr1 = ast_strdupa((char *) data))) {
ptr2 = ptr1;
/* Separate the Application data ptr1 is the time spec ptr2 is the app|data*/
strsep(&ptr2,"?");
Russell Bryant
committed
if(!(res = ast_build_timing(&timing, ptr1))) {
ast_log(LOG_WARNING, "Invalid Time Spec: %s\nCorrect usage: %s\n", ptr1, usage);
res = -1;
}
if (!res && ast_check_timing(&timing)) {
if (ptr2) {
/* ptr2 is now the app name
we're done with ptr1 now so recycle it and use it to point to the app args*/
struct ast_app *app;
if((ptr1 = strchr(ptr2, '|'))) {
*ptr1 = '\0';
ptr1++;
}
if ((app = pbx_findapp(ptr2))) {
res = pbx_exec(chan, app, ptr1 ? ptr1 : "", 1);
} else {
ast_log(LOG_WARNING, "Cannot locate application %s\n", ptr2);
}
} else {
ast_log(LOG_WARNING, "%s\n", usage);
}
}
} else {
ast_log(LOG_ERROR, "Memory Error!\n");
static int pbx_builtin_wait(struct ast_channel *chan, void *data)
if (data && atof((char *)data)) {
ms = atof((char *)data) * 1000;
static int pbx_builtin_waitexten(struct ast_channel *chan, void *data)
{
Mark Spencer
committed
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
int ms, res, argc;
char *args;
char *argv[2];
char *options = NULL;
char *mohclass = NULL;
char *timeout = NULL;
struct ast_flags flags = {0};
args = ast_strdupa(data);
if ((argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
if (argc > 0) {
timeout = argv[0];
if (argc > 1)
options = argv[1];
}
}
if (options) {
char *opts[1];
ast_parseoptions(waitexten_opts, &flags, opts, options);
if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
mohclass = opts[0];
}
}
if (ast_test_flag(&flags, WAITEXTEN_MOH))
ast_moh_start(chan, mohclass);
Mark Spencer
committed
if (timeout && atof((char *)timeout))
ms = atof((char *)timeout) * 1000;
else if (chan->pbx)
ms = chan->pbx->rtimeout * 1000;
else
ms = 10000;
res = ast_waitfordigit(chan, ms);
if (!res) {
Mark Spencer
committed
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1, chan->cid.cid_num)) {
Mark Spencer
committed
ast_verbose(VERBOSE_PREFIX_3 "Timeout on %s, continuing...\n", chan->name);
} else if (ast_exists_extension(chan, chan->context, "t", 1, chan->cid.cid_num)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Timeout on %s, going to 't'\n", chan->name);
ast_copy_string(chan->exten, "t", sizeof(chan->exten));
chan->priority = 0;
} else {
ast_log(LOG_WARNING, "Timeout but no rule 't' in context '%s'\n", chan->context);
res = -1;
}
Mark Spencer
committed
if (ast_test_flag(&flags, WAITEXTEN_MOH))
ast_moh_stop(chan);
static int pbx_builtin_background(struct ast_channel *chan, void *data)
Mark Spencer
committed
int argc;
char *args;
char *argv[3];
char *options = NULL;
char *filename = NULL;
char *front = NULL, *back = NULL;
Mark Spencer
committed
char *lang = NULL;
struct ast_flags flags = {0};
Mark Spencer
committed
args = ast_strdupa(data);
Mark Spencer
committed
if ((argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
if (argc > 0) {
filename = argv[0];
if (argc > 1)
options = argv[1];
if (argc > 2)
lang = argv[2];
} else {
ast_log(LOG_WARNING, "Background requires an argument (filename)\n");
}
}
if (!lang)
lang = chan->language;
Mark Spencer
committed
if (options) {
if (!strcasecmp(options, "skip"))
flags.flags = BACKGROUND_SKIP;
else if (!strcasecmp(options, "noanswer"))
flags.flags = BACKGROUND_NOANSWER;
else
ast_parseoptions(background_opts, &flags, NULL, options);
}
/* Answer if need be */
if (chan->_state != AST_STATE_UP) {
Mark Spencer
committed
if (ast_test_flag(&flags, BACKGROUND_SKIP)) {
Mark Spencer
committed
} else if (!ast_test_flag(&flags, BACKGROUND_NOANSWER)) {
res = ast_answer(chan);
}
}
if (!res) {
/* Stop anything playing */
ast_stopstream(chan);
/* Stream a file */
front = filename;
while(!res && front) {
if((back = strchr(front, '&'))) {
*back = '\0';
back++;
}
res = ast_streamfile(chan, front, lang);
if (!res) {
res = ast_waitstream(chan, AST_DIGIT_ANY);
ast_stopstream(chan);
} else {
ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char*)data);
res = 0;
break;
}
front = back;
static int pbx_builtin_atimeout(struct ast_channel *chan, void *data)
{
Kevin P. Fleming
committed
static int deprecation_warning = 0;
Kevin P. Fleming
committed
if (!deprecation_warning) {
ast_log(LOG_WARNING, "AbsoluteTimeout is deprecated, please use Set(TIMEOUT(absolute)=timeout) instead.\n");
Kevin P. Fleming
committed
deprecation_warning = 1;
}
/* Set the absolute maximum time how long a call can be connected */
ast_channel_setwhentohangup(chan,x);
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Set Absolute Timeout to %d\n", x);
return 0;
}
static int pbx_builtin_rtimeout(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
static int deprecation_warning = 0;
if (!deprecation_warning) {
ast_log(LOG_WARNING, "ResponseTimeout is deprecated, please use Set(TIMEOUT(response)=timeout) instead.\n");
Kevin P. Fleming
committed
deprecation_warning = 1;
}
Kevin P. Fleming
committed
/* If the channel is not in a PBX, return now */
if (!chan->pbx)
return 0;
/* 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;
}
static int pbx_builtin_dtimeout(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
static int deprecation_warning = 0;
if (!deprecation_warning) {
ast_log(LOG_WARNING, "DigitTimeout is deprecated, please use Set(TIMEOUT(digit)=timeout) instead.\n");
Kevin P. Fleming
committed
deprecation_warning = 1;
}
Kevin P. Fleming
committed
/* If the channel is not in a PBX, return now */
if (!chan->pbx)
return 0;
/* 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;
}
static int pbx_builtin_goto(struct ast_channel *chan, void *data)
int res;
res = ast_parseable_goto(chan, (const char *) data);
if (!res && (option_verbose > 2))
ast_verbose( VERBOSE_PREFIX_3 "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
int pbx_builtin_serialize_variables(struct ast_channel *chan, char *buf, size_t size)
{
struct ast_var_t *variables;
struct varshead *headp;
char *var=NULL ,*val=NULL;
int total = 0;
memset(buf,0,size);
if (chan) {
headp=&chan->varshead;
AST_LIST_TRAVERSE(headp,variables,entries) {
if(chan && variables && (var=ast_var_name(variables)) && (val=ast_var_value(variables)) && !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
snprintf(buf + strlen(buf), size - strlen(buf), "%s=%s\n", var, val);
if(strlen(buf) >= size) {
ast_log(LOG_ERROR,"Data Buffer Size Exceeded!\n");
break;
}
total++;
}
}
return total;
}
char *pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
struct ast_var_t *variables;
struct varshead *headp;
if (chan)
headp=&chan->varshead;
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);
}
}
}
void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
struct varshead *headp;
if (name[strlen(name)-1] == ')')
return ast_func_write(chan, name, value);
Kevin P. Fleming
committed
headp = (chan) ? &chan->varshead : &globals;
AST_LIST_TRAVERSE (headp, newvariable, entries) {
if (strcasecmp(ast_var_name(newvariable), name) == 0) {
/* there is already such a variable, delete it */
AST_LIST_REMOVE(headp, newvariable, entries);
ast_var_delete(newvariable);
break;
}
}
if (value) {
if ((option_verbose > 1) && (headp == &globals))
Kevin P. Fleming
committed
ast_verbose(VERBOSE_PREFIX_2 "Setting global variable '%s' to '%s'\n", name, value);
newvariable = ast_var_assign(name, value);
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
int pbx_builtin_setvar_old(struct ast_channel *chan, void *data)
{
static int deprecation_warning = 0;
if (!deprecation_warning) {
ast_log(LOG_WARNING, "SetVar is deprecated, please use Set instead.\n");
deprecation_warning = 1;
}
return pbx_builtin_setvar(chan, data);
}
Martin Pycko
committed
int pbx_builtin_setvar(struct ast_channel *chan, void *data)
Kevin P. Fleming
committed
char *name, *value, *mydata;
int argc;
char *argv[24]; /* this will only support a maximum of 24 variables being set in a single operation */
int global = 0;
int x;
Kevin P. Fleming
committed
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Set requires at least one variable name/value pair.\n");
Kevin P. Fleming
committed
return 0;
}
Kevin P. Fleming
committed
mydata = ast_strdupa(data);
argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
/* check for a trailing flags argument */
if ((argc > 1) && !strchr(argv[argc-1], '=')) {
argc--;
if (strchr(argv[argc], 'g'))
global = 1;
Kevin P. Fleming
committed
for (x = 0; x < argc; x++) {
name = argv[x];
if ((value = strchr(name, '='))) {
*value = '\0';
value++;
pbx_builtin_setvar_helper((global) ? NULL : chan, name, value);
} else
ast_log(LOG_WARNING, "Ignoring entry '%s' with no = (and not last 'options' entry)\n", name);
}
int pbx_builtin_importvar(struct ast_channel *chan, void *data)
{
char *name;
char *value;
char *stringp=NULL;
char *channel;
Kevin P. Fleming
committed
struct ast_channel *chan2;
char tmp[4096]="";
char *s;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Ignoring, since there is no variable to set\n");
return 0;
}
stringp = ast_strdupa(data);
name = strsep(&stringp,"=");
channel = strsep(&stringp,"|");
value = strsep(&stringp,"\0");
if (channel && value && name) {
Kevin P. Fleming
committed
chan2 = ast_get_channel_by_name_locked(channel);
if (chan2) {
s = alloca(strlen(value) + 4);
if (s) {
sprintf(s, "${%s}", value);
pbx_substitute_variables_helper(chan2, s, tmp, sizeof(tmp) - 1);
}
ast_mutex_unlock(&chan2->lock);
}
pbx_builtin_setvar_helper(chan, name, tmp);
}
return(0);
}
static int pbx_builtin_setglobalvar(struct ast_channel *chan, void *data)
{
char *name;
char *value;
char *stringp = NULL;
if (!data || ast_strlen_zero(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_REMOVE_HEAD(&globals, entries);
ast_var_delete(vardata);
}
}
static int pbx_checkcondition(char *condition)
{
return condition ? atoi(condition) : 0;
}
static int pbx_builtin_gotoif(struct ast_channel *chan, void *data)
{
char *condition,*branch1,*branch2,*branch;
char *s;
int rc;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Ignoring, since there is no variable to check\n");
stringp=s;
condition=strsep(&stringp,"?");
branch1=strsep(&stringp,":");
branch2=strsep(&stringp,"");
branch = pbx_checkcondition(condition) ? branch1 : branch2;
if ((branch==NULL) || ast_strlen_zero(branch)) {
ast_log(LOG_DEBUG, "Not taking any branch\n");
return(0);
}
rc=pbx_builtin_goto(chan,branch);
static int pbx_builtin_saynumber(struct ast_channel *chan, void *data)
{
int res = 0;
Mark Spencer
committed
char tmp[256];
char *number = (char *) NULL;
char *options = (char *) NULL;
if (!data || ast_strlen_zero((char *)data)) {
ast_log(LOG_WARNING, "SayNumber requires an argument (number)\n");
return -1;
}
ast_copy_string(tmp, (char *) data, sizeof(tmp));
number=tmp;
strsep(&number, "|");
options = strsep(&number, "|");
if (options) {
Mark Spencer
committed
if ( strcasecmp(options, "f") && strcasecmp(options,"m") &&
strcasecmp(options, "c") && strcasecmp(options, "n") ) {
ast_log(LOG_WARNING, "SayNumber gender option is either 'f', 'm', 'c' or 'n'\n");
return -1;
Mark Spencer
committed
}
}
return res = ast_say_number(chan, atoi((char *) tmp), "", chan->language, options);
}
static int pbx_builtin_saydigits(struct ast_channel *chan, void *data)
{
int res = 0;
if (data)
res = ast_say_digit_str(chan, (char *)data, "", chan->language);
static int pbx_builtin_saycharacters(struct ast_channel *chan, void *data)
{
int res = 0;
if (data)
res = ast_say_character_str(chan, (char *)data, "", chan->language);
return res;
}
static int pbx_builtin_sayphonetic(struct ast_channel *chan, void *data)
{
int res = 0;
if (data)
res = ast_say_phonetic_str(chan, (char *)data, "", chan->language);
return res;
}
/* Initialize the PBX */
if (option_verbose) {
ast_verbose( "Asterisk PBX Core Initializing\n");
ast_verbose( "Registering builtin applications:\n");
}
AST_LIST_HEAD_INIT(&globals);
ast_cli_register_multiple(pbx_cli, sizeof(pbx_cli) / sizeof(pbx_cli[0]));
/* Register builtin applications */
for (x=0; x<sizeof(builtins) / sizeof(struct pbx_builtin); x++) {
if (option_verbose)
ast_verbose( VERBOSE_PREFIX_1 "[%s]\n", builtins[x].name);
if (ast_register_application(builtins[x].name, builtins[x].execute, builtins[x].synopsis, builtins[x].description)) {
ast_log(LOG_ERROR, "Unable to register builtin application '%s'\n", builtins[x].name);
return -1;
}
}
return 0;
}
/*
* Lock context list functions ...
*/
int ast_lock_contexts()
{
return ast_mutex_lock(&conlock);
return ast_mutex_unlock(&conlock);
}
/*
* Lock context ...
*/
int ast_lock_context(struct ast_context *con)
{
return ast_mutex_lock(&con->lock);
}
int ast_unlock_context(struct ast_context *con)
{
return ast_mutex_unlock(&con->lock);