diff options
author | mnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-07-29 13:45:11 +0000 |
---|---|---|
committer | mnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-07-29 13:45:11 +0000 |
commit | fd53cfe17b54ed9491a1d87a7e94cf41e6de2020 (patch) | |
tree | 9d8127f7bf5ab69a181533388974b755eb970c8f /channels | |
parent | e6e2c4f9b4a784c5574052fa8a8ff539050f3cd5 (diff) |
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/
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@280306 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_local.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c index 8c826626a..a26b8f718 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -76,6 +76,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 = { @@ -98,6 +99,7 @@ static const struct ast_channel_tech local_tech = { .send_text = local_sendtext, .devicestate = local_devicestate, .bridged_channel = local_bridgedchannel, + .queryoption = local_queryoption, }; struct local_pvt { @@ -203,6 +205,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) { |