Dial: Add function to append already-created channel.

The Dial API takes responsiblity for creating an outbound channel when
calling ast_dial_append(). This commit adds a new function,
ast_dial_append_channel(), which allows us to create the channel outside
the Dial API and then to append the channel to the ast_dial structure.

This is useful for situations where the channel's creation and dialing
are distinct operations. Upcoming ARI early bridge work will illustrate
its usage.

ASTERISK-25889

Change-Id: Id8179f64f8f99132f80dead8d5db2030fd2c0509
This commit is contained in:
Mark Michelson 2016-03-30 16:47:15 -05:00 committed by Richard Mudgett
parent 23d2a561d5
commit ef4d3f1328
2 changed files with 87 additions and 32 deletions

View File

@ -76,6 +76,18 @@ struct ast_dial *ast_dial_create(void);
*/
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids);
/*!
* \brief Append a channel using an actual channel object
*
* \param dial The ast_dial to add the channel to
* \param chan The channel to add to the dial
* \retval -1 Failure
* \retval non-zero The position of the channel in the list of dialed channels
*
* \note The chan ref is stolen with a successful return.
*/
int ast_dial_append_channel(struct ast_dial *dial, struct ast_channel *chan);
/*! \brief Request all appended channels, but do not dial
* \param dial Dialing structure
* \param chan Optional dialing channel

View File

@ -248,22 +248,9 @@ struct ast_dial *ast_dial_create(void)
return dial;
}
/*! \brief Append a channel
* \note Appends a channel to a dialing structure
* \return Returns channel reference number on success, -1 on failure
*/
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
static int dial_append_common(struct ast_dial *dial, struct ast_dial_channel *channel,
const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
{
struct ast_dial_channel *channel = NULL;
/* Make sure we have required arguments */
if (!dial || !tech || !device)
return -1;
/* Allocate new memory for dialed channel structure */
if (!(channel = ast_calloc(1, sizeof(*channel))))
return -1;
/* Record technology and device for when we actually dial */
channel->tech = ast_strdup(tech);
channel->device = ast_strdup(device);
@ -287,6 +274,60 @@ int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device,
AST_LIST_INSERT_TAIL(&dial->channels, channel, list);
return channel->num;
}
/*! \brief Append a channel
* \note Appends a channel to a dialing structure
* \return Returns channel reference number on success, -1 on failure
*/
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
{
struct ast_dial_channel *channel = NULL;
/* Make sure we have required arguments */
if (!dial || !tech || !device)
return -1;
/* Allocate new memory for dialed channel structure */
if (!(channel = ast_calloc(1, sizeof(*channel))))
return -1;
return dial_append_common(dial, channel, tech, device, assignedids);
}
int ast_dial_append_channel(struct ast_dial *dial, struct ast_channel *chan)
{
struct ast_dial_channel *channel;
char *tech;
char *device;
char *dash;
if (!dial || !chan) {
return -1;
}
channel = ast_calloc(1, sizeof(*channel));
if (!channel) {
return -1;
}
channel->owner = chan;
tech = ast_strdupa(ast_channel_name(chan));
device = strchr(tech, '/');
if (!device) {
ast_free(channel);
return -1;
}
*device++ = '\0';
dash = strrchr(device, '-');
if (dash) {
*dash = '\0';
}
return dial_append_common(dial, channel, tech, device, NULL);
}
/*! \brief Helper function that requests all channels */
@ -315,27 +356,29 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
}
}
/* Copy device string over */
ast_copy_string(numsubst, channel->device, sizeof(numsubst));
if (!channel->owner) {
/* Copy device string over */
ast_copy_string(numsubst, channel->device, sizeof(numsubst));
if (cap && ast_format_cap_count(cap)) {
cap_request = cap;
} else if (requester_cap) {
cap_request = requester_cap;
} else {
cap_all_audio = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
ast_format_cap_append_by_type(cap_all_audio, AST_MEDIA_TYPE_AUDIO);
cap_request = cap_all_audio;
}
if (cap && ast_format_cap_count(cap)) {
cap_request = cap;
} else if (requester_cap) {
cap_request = requester_cap;
} else {
cap_all_audio = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
ast_format_cap_append_by_type(cap_all_audio, AST_MEDIA_TYPE_AUDIO);
cap_request = cap_all_audio;
}
/* If we fail to create our owner channel bail out */
if (!(channel->owner = ast_request(channel->tech, cap_request, &assignedids, chan, numsubst, &channel->cause))) {
/* If we fail to create our owner channel bail out */
if (!(channel->owner = ast_request(channel->tech, cap_request, &assignedids, chan, numsubst, &channel->cause))) {
ao2_cleanup(cap_all_audio);
return -1;
}
cap_request = NULL;
ao2_cleanup(requester_cap);
ao2_cleanup(cap_all_audio);
return -1;
}
cap_request = NULL;
ao2_cleanup(requester_cap);
ao2_cleanup(cap_all_audio);
if (chan) {
ast_channel_lock_both(chan, channel->owner);