diff options
-rwxr-xr-x | include/asterisk/pbx.h | 4 | ||||
-rwxr-xr-x | manager.c | 23 | ||||
-rwxr-xr-x | pbx.c | 31 | ||||
-rwxr-xr-x | pbx/pbx_spool.c | 4 |
4 files changed, 47 insertions, 15 deletions
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index c45611fea..5e05c43a5 100755 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -526,11 +526,11 @@ int ast_async_goto_by_name(const char *chan, const char *context, const char *ex /* Synchronously or asynchronously make an outbound call and send it to a particular extension */ -int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account ); +int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account, struct ast_channel **locked_channel); /* Synchronously or asynchronously make an outbound call and send it to a particular application with given extension */ -int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account); +int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account, struct ast_channel **locked_channel); /* Functions for returning values from structures */ const char *ast_get_context_name(struct ast_context *con); @@ -823,16 +823,18 @@ static void *fast_originate(void *data) struct fast_originate_helper *in = data; int res; int reason = 0; + struct ast_channel *chan = NULL; + if (!ast_strlen_zero(in->app)) { res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, !ast_strlen_zero(in->cid_num) ? in->cid_num : NULL, !ast_strlen_zero(in->cid_name) ? in->cid_name : NULL, - in->variable, in->account); + in->variable, in->account, &chan); } else { res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, !ast_strlen_zero(in->cid_num) ? in->cid_num : NULL, !ast_strlen_zero(in->cid_name) ? in->cid_name : NULL, - in->variable, in->account); + in->variable, in->account, &chan); } if (!res) manager_event(EVENT_FLAG_CALL, @@ -841,8 +843,9 @@ static void *fast_originate(void *data) "Channel: %s/%s\r\n" "Context: %s\r\n" "Exten: %s\r\n" - "Reason: %i\r\n", - in->idtext, in->tech, in->data, in->context, in->exten, reason); + "Reason: %i\r\n" + "Uniqueid: %s\r\n", + in->idtext, in->tech, in->data, in->context, in->exten, reason, chan ? chan->uniqueid : "<null>"); else manager_event(EVENT_FLAG_CALL, "OriginateFailure", @@ -850,9 +853,13 @@ static void *fast_originate(void *data) "Channel: %s/%s\r\n" "Context: %s\r\n" "Exten: %s\r\n" - "Reason: %i\r\n", - in->idtext, in->tech, in->data, in->context, in->exten, reason); + "Reason: %i\r\n" + "Uniqueid: %s\r\n", + in->idtext, in->tech, in->data, in->context, in->exten, reason, chan ? chan->uniqueid : "<null>"); + /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ + if (chan) + ast_mutex_unlock(&chan->lock); free(in); return NULL; } @@ -961,10 +968,10 @@ static int action_originate(struct mansession *s, struct message *m) } } } else if (!ast_strlen_zero(app)) { - res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 0, l, n, variable, account); + res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 0, l, n, variable, account, NULL); } else { if (exten && context && pi) - res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0, l, n, variable, account); + res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0, l, n, variable, account, NULL); else { astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); return 0; @@ -4352,7 +4352,7 @@ int ast_pbx_outgoing_cdr_failed(void) return 0; /* success */ } -int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account) +int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account, struct ast_channel **channel) { struct ast_channel *chan; struct async_stat *as; @@ -4364,6 +4364,11 @@ int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout if (sync) { LOAD_OH(oh); chan = __ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name, &oh); + if (channel) { + *channel = chan; + if (chan) + ast_mutex_lock(&chan->lock); + } if (chan) { if (account) @@ -4452,6 +4457,11 @@ int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout return -1; memset(as, 0, sizeof(struct async_stat)); chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); + if (channel) { + *channel = chan; + if (chan) + ast_mutex_lock(&chan->lock); + } if (!chan) { free(as); return -1; @@ -4504,7 +4514,7 @@ static void *ast_pbx_run_app(void *data) return NULL; } -int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account) +int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, const char *variable, const char *account, struct ast_channel **locked_channel) { struct ast_channel *chan; struct async_stat *as; @@ -4513,12 +4523,13 @@ int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, int res = -1, cdr_res = -1; pthread_attr_t attr; + if (locked_channel) + *locked_channel = NULL; if (!app || ast_strlen_zero(app)) return -1; if (sync) { chan = ast_request_and_dial(type, format, data, timeout, reason, cid_num, cid_name); if (chan) { - if (account) ast_cdr_setaccount(chan, account); @@ -4558,11 +4569,18 @@ int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, } else { 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); ast_hangup(chan); res = -1; + } else { + if (locked_channel) + *locked_channel = chan; } } } else { @@ -4616,11 +4634,18 @@ int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, /* 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); ast_hangup(chan); return -1; + } else { + if (locked_channel) + *locked_channel = chan; } res = 0; } diff --git a/pbx/pbx_spool.c b/pbx/pbx_spool.c index 7e82d746b..94f867a02 100755 --- a/pbx/pbx_spool.c +++ b/pbx/pbx_spool.c @@ -224,11 +224,11 @@ static void *attempt_thread(void *data) if (!ast_strlen_zero(o->app)) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries); - res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->variable, o->account); + res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->variable, o->account, NULL); } else { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries); - res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->variable, o->account); + res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->variable, o->account, NULL); } if (res) { ast_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason); |