diff -urN asterisk-1.6.2.6-rc1_orig/channels/chan_local.c asterisk-1.6.2.6-rc1/channels/chan_local.c --- asterisk-1.6.2.6-rc1_orig/channels/chan_local.c 2010-03-05 16:47:36.000000000 +0100 +++ asterisk-1.6.2.6-rc1/channels/chan_local.c 2010-03-05 16:52:47.000000000 +0100 @@ -121,6 +121,7 @@ #define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */ #define LOCAL_BRIDGE (1 << 5) /*!< Report back the "true" channel as being bridged to */ #define LOCAL_MOH_PASSTHRU (1 << 6) /*!< Pass through music on hold start/stop frames */ +#define LOCAL_OPTIMIZE_ON_TRANSFER (1 << 7) /*!< Optimize, but only on transfers */ static AST_LIST_HEAD_STATIC(locals, local_pvt); @@ -292,6 +293,15 @@ if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner || (p->chan->_bridge != ast_bridged_channel(p->chan))) return; + /* Optimize on direct xfer */ + if (ast_test_flag(p, LOCAL_OPTIMIZE_ON_TRANSFER) && !strcasecmp(p->context, p->chan->context) && !strcasecmp(p->exten, p->chan->exten)) { + return; + } + else if (ast_test_flag(p, LOCAL_OPTIMIZE_ON_TRANSFER)) { // Direct transfer detected via goto + ast_log(LOG_DEBUG, "Direct transfer detected, from %s->%s to %s->%s\n", p->context, p->exten, p->chan->context, p->chan->exten); + ast_clear_flag(p, LOCAL_OPTIMIZE_ON_TRANSFER); + } + /* only do the masquerade if we are being called on the outbound channel, if it has been bridged to another channel and if there are no pending frames on the owner channel (because they would be transferred to the @@ -398,6 +408,13 @@ ast_mutex_unlock(&p->lock); return -1; } + + /* Optimize on attended xfer */ + if(ast_test_flag(p, LOCAL_OPTIMIZE_ON_TRANSFER) && p->chan == oldchan) { + ast_log(LOG_DEBUG, "Attended transfer detected\n"); + ast_clear_flag(p, LOCAL_OPTIMIZE_ON_TRANSFER); + } + if (p->owner == oldchan) p->owner = newchan; else @@ -700,6 +717,9 @@ if (strchr(opts, 'm')) { ast_set_flag(tmp, LOCAL_MOH_PASSTHRU); } + if (strchr(opts, 't')) { + ast_set_flag(tmp, LOCAL_OPTIMIZE_ON_TRANSFER); + } } /* Look for a context */