summaryrefslogtreecommitdiff
path: root/channels/chan_iax2.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2013-05-21 18:00:22 +0000
committerRichard Mudgett <rmudgett@digium.com>2013-05-21 18:00:22 +0000
commit3d63833bd6c869b7efa383e8dea14be1a6eff998 (patch)
tree34957dd051b8f67c7cc58a510e24ee3873a61ad4 /channels/chan_iax2.c
parente1e1cc2deefb92f8b43825f1f34e619354737842 (diff)
Merge in the bridge_construction branch to make the system use the Bridging API.
Breaks many things until they can be reworked. A partial list: chan_agent chan_dahdi, chan_misdn, chan_iax2 native bridging app_queue COLP updates DTMF attended transfers Protocol attended transfers git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389378 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r--channels/chan_iax2.c172
1 files changed, 11 insertions, 161 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 112a99375..49ce66cb7 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -102,6 +102,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/data.h"
#include "asterisk/netsock2.h"
#include "asterisk/security_events.h"
+#include "asterisk/bridging.h"
#include "iax2/include/iax2.h"
#include "iax2/include/firmware.h"
@@ -1258,6 +1259,7 @@ static void sched_delay_remove(struct sockaddr_in *sin, callno_entry entry);
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message);
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message);
+/* BUGBUG The IAX2 channel driver needs its own native bridge technology. */
static struct ast_channel_tech iax2_tech = {
.type = "IAX2",
.description = tdesc,
@@ -9221,130 +9223,6 @@ static void spawn_dp_lookup(int callno, const char *context, const char *calledn
}
}
-struct iax_dual {
- struct ast_channel *chan1;
- struct ast_channel *chan2;
- char *park_exten;
- char *park_context;
-};
-
-static void *iax_park_thread(void *stuff)
-{
- struct iax_dual *d;
- int res;
- int ext = 0;
-
- d = stuff;
-
- ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
- ast_channel_name(d->chan2), ast_channel_name(d->chan1));
-
- res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
- if (res) {
- /* Parking failed. */
- ast_hangup(d->chan1);
- } else {
- ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
- }
- ast_hangup(d->chan2);
-
- ast_free(d->park_exten);
- ast_free(d->park_context);
- ast_free(d);
- return NULL;
-}
-
-/*! DO NOT hold any locks while calling iax_park */
-static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
-{
- struct iax_dual *d;
- struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */
- pthread_t th;
-
- chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), ast_channel_exten(chan1), ast_channel_context(chan1), ast_channel_linkedid(chan1), ast_channel_amaflags(chan1), "Parking/%s", ast_channel_name(chan1));
- chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), ast_channel_exten(chan2), ast_channel_context(chan2), ast_channel_linkedid(chan2), ast_channel_amaflags(chan2), "IAXPeer/%s", ast_channel_name(chan2));
- d = ast_calloc(1, sizeof(*d));
- if (!chan1m || !chan2m || !d) {
- if (chan1m) {
- ast_hangup(chan1m);
- }
- if (chan2m) {
- ast_hangup(chan2m);
- }
- ast_free(d);
- return -1;
- }
- d->park_exten = ast_strdup(park_exten);
- d->park_context = ast_strdup(park_context);
- if (!d->park_exten || !d->park_context) {
- ast_hangup(chan1m);
- ast_hangup(chan2m);
- ast_free(d->park_exten);
- ast_free(d->park_context);
- ast_free(d);
- return -1;
- }
-
- /* Make formats okay */
- ast_format_copy(ast_channel_readformat(chan1m), ast_channel_readformat(chan1));
- ast_format_copy(ast_channel_writeformat(chan1m), ast_channel_writeformat(chan1));
-
- /* Prepare for taking over the channel */
- if (ast_channel_masquerade(chan1m, chan1)) {
- ast_hangup(chan1m);
- ast_hangup(chan2m);
- ast_free(d->park_exten);
- ast_free(d->park_context);
- ast_free(d);
- return -1;
- }
-
- /* Setup the extensions and such */
- ast_channel_context_set(chan1m, ast_channel_context(chan1));
- ast_channel_exten_set(chan1m, ast_channel_exten(chan1));
- ast_channel_priority_set(chan1m, ast_channel_priority(chan1));
-
- ast_do_masquerade(chan1m);
-
- /* We make a clone of the peer channel too, so we can play
- back the announcement */
-
- /* Make formats okay */
- ast_format_copy(ast_channel_readformat(chan2m), ast_channel_readformat(chan2));
- ast_format_copy(ast_channel_writeformat(chan2m), ast_channel_writeformat(chan2));
- ast_channel_parkinglot_set(chan2m, ast_channel_parkinglot(chan2));
-
- /* Prepare for taking over the channel */
- if (ast_channel_masquerade(chan2m, chan2)) {
- ast_hangup(chan1m);
- ast_hangup(chan2m);
- ast_free(d->park_exten);
- ast_free(d->park_context);
- ast_free(d);
- return -1;
- }
-
- /* Setup the extensions and such */
- ast_channel_context_set(chan2m, ast_channel_context(chan2));
- ast_channel_exten_set(chan2m, ast_channel_exten(chan2));
- ast_channel_priority_set(chan2m, ast_channel_priority(chan2));
-
- ast_do_masquerade(chan2m);
-
- d->chan1 = chan1m; /* Transferee */
- d->chan2 = chan2m; /* Transferer */
- if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
- /* Could not start thread */
- ast_hangup(chan1m);
- ast_hangup(chan2m);
- ast_free(d->park_exten);
- ast_free(d->park_context);
- ast_free(d);
- return -1;
- }
- return 0;
-}
-
static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
{
unsigned int ourver;
@@ -10774,56 +10652,28 @@ static int socket_process_helper(struct iax2_thread *thread)
break;
case IAX_COMMAND_TRANSFER:
{
- struct ast_channel *bridged_chan;
- struct ast_channel *owner;
-
iax2_lock_owner(fr->callno);
if (!iaxs[fr->callno]) {
/* Initiating call went away before we could transfer. */
break;
}
- owner = iaxs[fr->callno]->owner;
- bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
- if (bridged_chan && ies.called_number) {
- const char *context;
-
- context = ast_strdupa(iaxs[fr->callno]->context);
+ if (iaxs[fr->callno]->owner) {
+ struct ast_channel *owner = iaxs[fr->callno]->owner;
+ char *context = ast_strdupa(iaxs[fr->callno]->context);
ast_channel_ref(owner);
- ast_channel_ref(bridged_chan);
ast_channel_unlock(owner);
ast_mutex_unlock(&iaxsl[fr->callno]);
- /* Set BLINDTRANSFER channel variables */
- pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", ast_channel_name(bridged_chan));
- pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", ast_channel_name(owner));
-
- /* DO NOT hold any locks while calling ast_parking_ext_valid() */
- if (ast_parking_ext_valid(ies.called_number, owner, context)) {
- ast_debug(1, "Parking call '%s'\n", ast_channel_name(bridged_chan));
- if (iax_park(bridged_chan, owner, ies.called_number, context)) {
- ast_log(LOG_WARNING, "Failed to park call '%s'\n",
- ast_channel_name(bridged_chan));
- }
- } else {
- if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
- ast_log(LOG_WARNING,
- "Async goto of '%s' to '%s@%s' failed\n",
- ast_channel_name(bridged_chan), ies.called_number, context);
- } else {
- ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
- ast_channel_name(bridged_chan), ies.called_number, context);
- }
+ if (ast_bridge_transfer_blind(owner, ies.called_number,
+ context, NULL, NULL) != AST_BRIDGE_TRANSFER_SUCCESS) {
+ ast_log(LOG_WARNING, "Blind transfer of '%s' to '%s@%s' failed\n",
+ ast_channel_name(owner), ies.called_number,
+ context);
}
- ast_channel_unref(owner);
- ast_channel_unref(bridged_chan);
+ ast_channel_unref(owner);
ast_mutex_lock(&iaxsl[fr->callno]);
- } else {
- ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
- if (owner) {
- ast_channel_unlock(owner);
- }
}
break;