Skip to content
This repository was archived by the owner on Jan 14, 2020. It is now read-only.

Commit

Permalink
Originated calls: Fix several originate call problems.
Browse files Browse the repository at this point in the history
* Restore the reason value set by pbx_outgoing_attempt() to use
AST_CONTROL_xxx values as all the consumers were expecting rather than
cause codes.

* Fixed the dial routines to set cause codes for more than just
ast_request() so pbx_outgoing_attempt() reason codes will function.

* Fix inconsistent locked_channel return status in pbx_outgoing_attempt().
The chanel may not have been locked or the channel may have been a stale
pointer.

* Fixed the OutgoingSpoolFailed channel to run dialplan whenever the
dialing fails for an originate exten and 1 < synchronous.

* Fix incorrect ast_cond_wait() usage in pbx_outgoing_attempt().
Indroduced by issue ASTERISK-22212 patch.

* Made struct pbx_outgoing use the ao2 lock instead of its own lock for
the cond wait mutex.  No sense in having two locks associated with the
same struct when only one is needed.

Review: https://reviewboard.asterisk.org/r/3421/
........

Merged revisions 412581 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: http://svn.asterisk.org/svn/asterisk/trunk@412583 f38db490-d61c-443f-a65b-d21fe96a405b
  • Loading branch information
rmudgett9125 committed Apr 18, 2014
1 parent 348ab66 commit 91b580c
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 106 deletions.
4 changes: 2 additions & 2 deletions apps/app_originate.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,14 @@ static int originate_exec(struct ast_channel *chan, const char *data)
chantech, chandata, args.arg1, exten, priority);

ast_pbx_outgoing_exten(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
timeout * 1000, args.arg1, exten, priority, &outgoing_status, 1, NULL,
NULL, NULL, NULL, NULL, 0, NULL);
} else if (!strcasecmp(args.type, "app")) {
ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
chantech, chandata, args.arg1, S_OR(args.arg2, ""));

ast_pbx_outgoing_app(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
timeout * 1000, args.arg1, args.arg2, &outgoing_status, 1, NULL,
NULL, NULL, NULL, NULL, NULL);
} else {
ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
Expand Down
62 changes: 37 additions & 25 deletions include/asterisk/pbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,8 @@ int ast_async_goto(struct ast_channel *chan, const char *context, const char *ex
*/
int ast_async_goto_by_name(const char *chan, const char *context, const char *exten, int priority);

/*! \brief Synchronously or asynchronously make an outbound call and send it to a
/*!
* \brief Synchronously or asynchronously make an outbound call and send it to a
* particular extension
*
* \param type The channel technology to create
Expand All @@ -1112,27 +1113,34 @@ int ast_async_goto_by_name(const char *chan, const char *context, const char *ex
* \param context The destination context for the outbound channel
* \param exten The destination extension for the outbound channel
* \param priority The destination priority for the outbound channel
* \param reason Optional. If provided, the hangup cause code of the outbound channel if
* it failed
* \param sync If non-zero, block until the outbound channel answers
* \param reason Optional. If provided, the dialed status of the outgoing channel.
* Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
* \param synchronous If zero then don't wait for anything.
* If one then block until the outbound channel answers or the call fails.
* If greater than one then wait for the call to complete or if the call doesn't
* answer and failed@context exists then run a channel named OutgoingSpoolFailed
* at failed@context.
* \param cid_num The caller ID number to set on the outbound channel
* \param cid_name The caller ID name to set on the outbound channel
* \param vars Variables to set on the outbound channel
* \param account The accountcode for the outbound channel
* \param locked_channel Optional. The outbound channel that was created. This is returned
* both locked and reference bumped. If a caller provides a channel parameter, it must
* unlock the channel and decrement the reference count.
* \param assignedid Optional. The uniqueid to assign the channel that was created.
* \param assignedid2 Optional. The uniqueid to assign the second local channel.
* \param early_media If non-zero, allow early-media on the originated channel
* \param locked_channel Optional. The outbound channel that was created if success
* is returned. Otherwise it is set to NULL. This is returned both locked
* and reference bumped.
* \param early_media If non-zero the channel "answers" when progress is indicated.
* \param assignedids Optional. The uniqueid(s) to assign the channel(s) that are created.
*
* \retval 0 on success
* \retval -1 on failure
*/
int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr,
int timeout, const char *context, const char *exten, int priority, int *reason,
int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars,
const char *account, struct ast_channel **locked_channel, int early_media,
int timeout, const char *context, const char *exten, int priority, int *reason,
int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars,
const char *account, struct ast_channel **locked_channel, int early_media,
const struct ast_assigned_ids *assignedids);

/*! \brief Synchronously or asynchronously make an outbound call and execute an
/*!
* \brief Synchronously or asynchronously make an outbound call and execute an
* application on the channel.
*
* Note that when the application stops executing, the channel is hungup.
Expand All @@ -1143,23 +1151,27 @@ int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const c
* \param timeout How long we should attempt to dial the outbound channel
* \param app The name of the application to execute
* \param appdata Data to pass to the application
* \param reason Optional. If provided, the hangup cause code of the outbound channel if
* it failed
* \param sync If non-zero, block until the outbound channel answers
* \param reason Optional. If provided, the dialed status of the outgoing channel.
* Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
* \param synchronous If zero then don't wait for anything.
* If one then block until the outbound channel answers or the call fails.
* If greater than one then wait for the call to complete.
* \param cid_num The caller ID number to set on the outbound channel
* \param cid_name The caller ID name to set on the outbound channel
* \param vars Variables to set on the outbound channel
* \param account The accountcode for the outbound channel
* \param locked_channel Optional. The outbound channel that was created. This is returned
* \param assignedid Optional. The uniqueid to assign the channel that was created.
* \param assignedid2 Optional. The uniqueid to assign the second local channel.
* both locked and reference bumped. If a caller provides a channel parameter, it must
* unlock the channel and decrement the reference count.
* \param locked_channel Optional. The outbound channel that was created if success
* is returned. Otherwise it is set to NULL. This is returned both locked
* and reference bumped.
* \param assignedids Optional. The uniqueid(s) to assign the channel(s) that are created.
*
* \retval 0 on success
* \retval -1 on failure
*/
int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr,
int timeout, const char *app, const char *appdata, int *reason, int sync,
const char *cid_num, const char *cid_name, struct ast_variable *vars,
const char *account, struct ast_channel **locked_channel,
int timeout, const char *app, const char *appdata, int *reason, int synchronous,
const char *cid_num, const char *cid_name, struct ast_variable *vars,
const char *account, struct ast_channel **locked_channel,
const struct ast_assigned_ids *assignedids);

/*!
Expand Down
24 changes: 19 additions & 5 deletions main/dial.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,14 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
ast_verb(3, "%s is busy\n", ast_channel_name(channel->owner));
ast_channel_publish_dial(chan, channel->owner, channel->device, "BUSY");
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_USER_BUSY;
channel->owner = NULL;
break;
case AST_CONTROL_CONGESTION:
ast_verb(3, "%s is circuit-busy\n", ast_channel_name(channel->owner));
ast_channel_publish_dial(chan, channel->owner, channel->device, "CONGESTION");
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
channel->owner = NULL;
break;
case AST_CONTROL_INCOMPLETE:
Expand Down Expand Up @@ -593,7 +595,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
break;
case AST_CONTROL_HOLD:
ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(chan));
ast_indicate(chan, AST_CONTROL_HOLD);
ast_indicate_data(chan, AST_CONTROL_HOLD, fr->data.ptr, fr->datalen);
break;
case AST_CONTROL_UNHOLD:
ast_verb(3, "Call on %s left from hold\n", ast_channel_name(chan));
Expand All @@ -613,8 +615,6 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
break;
}
}

return;
}

/*! \brief Helper function that handles control frames WITHOUT owner */
Expand All @@ -638,12 +638,25 @@ static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channe
ast_verb(3, "%s is busy\n", ast_channel_name(channel->owner));
ast_channel_publish_dial(NULL, channel->owner, channel->device, "BUSY");
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_USER_BUSY;
channel->owner = NULL;
break;
case AST_CONTROL_CONGESTION:
ast_verb(3, "%s is circuit-busy\n", ast_channel_name(channel->owner));
ast_channel_publish_dial(NULL, channel->owner, channel->device, "CONGESTION");
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
channel->owner = NULL;
break;
case AST_CONTROL_INCOMPLETE:
/*
* Nothing to do but abort the call since we have no
* controlling channel to ask for more digits.
*/
ast_verb(3, "%s dialed Incomplete extension %s\n",
ast_channel_name(channel->owner), ast_channel_exten(channel->owner));
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_UNALLOCATED;
channel->owner = NULL;
break;
case AST_CONTROL_RINGING:
Expand All @@ -661,8 +674,6 @@ static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channe
default:
break;
}

return;
}

/*! \brief Helper function to handle when a timeout occurs on dialing attempt */
Expand All @@ -686,6 +697,7 @@ static int handle_timeout_trip(struct ast_dial *dial, struct timeval start)
AST_LIST_TRAVERSE(&dial->channels, channel, list) {
if (dial->state == AST_DIAL_RESULT_TIMEOUT || diff >= channel->timeout) {
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_NO_ANSWER;
channel->owner = NULL;
} else if ((lowest_timeout == -1) || (lowest_timeout > channel->timeout)) {
lowest_timeout = channel->timeout;
Expand Down Expand Up @@ -835,6 +847,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann
ast_poll_channel_del(chan, channel->owner);
ast_channel_publish_dial(chan, channel->owner, channel->device, "CANCEL");
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_ANSWERED_ELSEWHERE;
channel->owner = NULL;
}
AST_LIST_UNLOCK(&dial->channels);
Expand All @@ -859,6 +872,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann
ast_poll_channel_del(chan, channel->owner);
ast_channel_publish_dial(chan, channel->owner, channel->device, "CANCEL");
ast_hangup(channel->owner);
channel->cause = AST_CAUSE_NORMAL_CLEARING;
channel->owner = NULL;
}
AST_LIST_UNLOCK(&dial->channels);
Expand Down
Loading

0 comments on commit 91b580c

Please sign in to comment.