diff options
author | Joshua Colp <jcolp@digium.com> | 2013-05-18 19:47:24 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2013-05-18 19:47:24 +0000 |
commit | 4e38a4eb6459ef79ebee61c87f144e0d5d0122eb (patch) | |
tree | e7faa017d2c0d21f6ca3f9007b27694763688204 /main/dial.c | |
parent | b97c71bb1190cb41eba9081d14724bcb39d422ba (diff) |
Move origination to use the dialing API and send Stasis messages on dial begin and end.
(closes issue ASTERISK-21549)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2512/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389053 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/dial.c')
-rw-r--r-- | main/dial.c | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/main/dial.c b/main/dial.c index da02f7a23..7008cd574 100644 --- a/main/dial.c +++ b/main/dial.c @@ -258,18 +258,19 @@ int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device) return channel->num; } -/*! \brief Helper function that does the beginning dialing per-appended channel */ -static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan) +/*! \brief Helper function that requests all channels */ +static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channel *chan, struct ast_format_cap *cap) { char numsubst[AST_MAX_EXTENSION]; - int res = 1; struct ast_format_cap *cap_all_audio = NULL; struct ast_format_cap *cap_request; /* Copy device string over */ ast_copy_string(numsubst, channel->device, sizeof(numsubst)); - if (chan) { + if (!ast_format_cap_is_empty(cap)) { + cap_request = cap; + } else if (chan) { cap_request = ast_channel_nativeformats(chan); } else { cap_all_audio = ast_format_cap_alloc_nolock(); @@ -311,6 +312,39 @@ static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_chann ast_channel_transfercapability_set(channel->owner, ast_channel_transfercapability(chan)); } + return 0; +} + +int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_format_cap *cap) +{ + struct ast_dial_channel *channel; + int res = -1; + + AST_LIST_LOCK(&dial->channels); + AST_LIST_TRAVERSE(&dial->channels, channel, list) { + if ((res = begin_dial_prerun(channel, chan, cap))) { + break; + } + } + AST_LIST_UNLOCK(&dial->channels); + + return res; +} + +/*! \brief Helper function that does the beginning dialing per-appended channel */ +static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan) +{ + char numsubst[AST_MAX_EXTENSION]; + int res = 1; + + /* If no owner channel exists yet execute pre-run */ + if (!channel->owner && begin_dial_prerun(channel, chan, NULL)) { + return 0; + } + + /* Copy device string over */ + ast_copy_string(numsubst, channel->device, sizeof(numsubst)); + /* Attempt to actually call this device */ if ((res = ast_call(channel->owner, numsubst, 0))) { res = 0; @@ -554,6 +588,11 @@ static int handle_timeout_trip(struct ast_dial *dial, struct timeval start) struct ast_dial_channel *channel = NULL; int diff = ast_tvdiff_ms(ast_tvnow(), start), lowest_timeout = -1, new_timeout = -1; + /* If there is no difference yet return the dial timeout so we can go again, we were likely interrupted */ + if (!diff) { + return dial->timeout; + } + /* If the global dial timeout tripped switch the state to timeout so our channel loop will drop every channel */ if (diff >= dial->timeout) { set_state(dial, AST_DIAL_RESULT_TIMEOUT); @@ -771,7 +810,7 @@ enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *cha enum ast_dial_result res = AST_DIAL_RESULT_TRYING; /* Ensure required arguments are passed */ - if (!dial || (!chan && !async)) { + if (!dial) { ast_debug(1, "invalid #1\n"); return AST_DIAL_RESULT_INVALID; } @@ -1102,6 +1141,28 @@ int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option return 0; } +int ast_dial_reason(struct ast_dial *dial, int num) +{ + struct ast_dial_channel *channel; + + if (!dial || AST_LIST_EMPTY(&dial->channels) || !(channel = find_dial_channel(dial, num))) { + return -1; + } + + return channel->cause; +} + +struct ast_channel *ast_dial_get_channel(struct ast_dial *dial, int num) +{ + struct ast_dial_channel *channel; + + if (!dial || AST_LIST_EMPTY(&dial->channels) || !(channel = find_dial_channel(dial, num))) { + return NULL; + } + + return channel->owner; +} + void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback) { dial->state_callback = callback; |