From 3def1196b4f42b0977cb03fe9421baca5ef79d29 Mon Sep 17 00:00:00 2001 From: Matthew Nicholson Date: Thu, 29 Jul 2010 14:03:59 +0000 Subject: Merged revisions 280307 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r280307 | mnicholson | 2010-07-29 08:56:35 -0500 (Thu, 29 Jul 2010) | 11 lines Merged revisions 280306 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ........ r280306 | mnicholson | 2010-07-29 08:45:11 -0500 (Thu, 29 Jul 2010) | 2 lines Implement support for ast_channel_queryoption on local channels. Currently only AST_OPTION_T38_STATE is supported. ABE-2229 Review: https://reviewboard.asterisk.org/r/813/ ........ Additionally, pass AST_CONTROL_T38_PARAMETERS control frames through generic bridges. This change appears to have been unintentionally left out of rev 203699. ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@280308 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_local.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'channels') diff --git a/channels/chan_local.c b/channels/chan_local.c index 95adfcab7..d1f66f8dd 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -94,6 +94,7 @@ static int local_sendhtml(struct ast_channel *ast, int subclass, const char *dat static int local_sendtext(struct ast_channel *ast, const char *text); static int local_devicestate(void *data); static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge); +static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen); /* PBX interface structure for channel registration */ static const struct ast_channel_tech local_tech = { @@ -116,6 +117,7 @@ static const struct ast_channel_tech local_tech = { .send_text = local_sendtext, .devicestate = local_devicestate, .bridged_channel = local_bridgedchannel, + .queryoption = local_queryoption, }; /*! \brief the local pvt structure for all channels @@ -228,6 +230,58 @@ static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct return bridged; } +static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen) +{ + struct local_pvt *p = ast->tech_pvt; + struct ast_channel *chan, *bridged; + int res; + + if (!p) { + return -1; + } + + if (option != AST_OPTION_T38_STATE) { + /* AST_OPTION_T38_STATE is the only supported option at this time */ + return -1; + } + + ast_mutex_lock(&p->lock); + chan = IS_OUTBOUND(ast, p) ? p->owner : p->chan; + +try_again: + if (!chan) { + ast_mutex_unlock(&p->lock); + return -1; + } + + if (ast_channel_trylock(chan)) { + DEADLOCK_AVOIDANCE(&p->lock); + chan = IS_OUTBOUND(ast, p) ? p->owner : p->chan; + goto try_again; + } + + bridged = ast_bridged_channel(chan); + if (!bridged) { + /* can't query channel unless we are bridged */ + ast_mutex_unlock(&p->lock); + ast_channel_unlock(chan); + return -1; + } + + if (ast_channel_trylock(bridged)) { + ast_channel_unlock(chan); + DEADLOCK_AVOIDANCE(&p->lock); + chan = IS_OUTBOUND(ast, p) ? p->owner : p->chan; + goto try_again; + } + + res = ast_channel_queryoption(bridged, option, data, datalen, 0); + ast_mutex_unlock(&p->lock); + ast_channel_unlock(chan); + ast_channel_unlock(bridged); + return res; +} + static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked) { -- cgit v1.2.3