From ef4d3f132892a0ce12649bea2f325803e9ad7076 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Wed, 30 Mar 2016 16:47:15 -0500 Subject: 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 --- main/dial.c | 107 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 32 deletions(-) (limited to 'main') diff --git a/main/dial.c b/main/dial.c index 127f327d1..80247588d 100644 --- a/main/dial.c +++ b/main/dial.c @@ -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); -- cgit v1.2.3