/* Called with ast locked */ static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen) { struct local_pvt *p; struct ast_channel *bridged = NULL; struct ast_channel *tmp = NULL; int res = 0; if (option != AST_OPTION_T38_STATE) { /* AST_OPTION_T38_STATE is the only supported option at this time */ return -1; } /* for some reason the channel is not locked in channel.c when this function is called */ if (!(p = ast_channel_tech_pvt(ast))) { return -1; } ao2_lock(p); if (!(tmp = IS_OUTBOUND(ast, p) ? p->owner : p->chan)) { ao2_unlock(p); return -1; } ast_channel_ref(tmp); ao2_unlock(p); ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */ ast_channel_lock(tmp); if (!(bridged = ast_bridged_channel(tmp))) { res = -1; ast_channel_unlock(tmp); goto query_cleanup; } ast_channel_ref(bridged); ast_channel_unlock(tmp); query_cleanup: if (bridged) { res = ast_channel_queryoption(bridged, option, data, datalen, 0); bridged = ast_channel_unref(bridged); } if (tmp) { tmp = ast_channel_unref(tmp); } ast_channel_lock(ast); /* Lock back before we leave */ return res; }
/* Called with ast locked */ int ast_unreal_queryoption(struct ast_channel *ast, int option, void *data, int *datalen) { struct ast_unreal_pvt *p; struct ast_channel *peer; struct ast_channel *other; int res = 0; if (option != AST_OPTION_T38_STATE) { /* AST_OPTION_T38_STATE is the only supported option at this time */ return -1; } /* for some reason the channel is not locked in channel.c when this function is called */ if (!(p = ast_channel_tech_pvt(ast))) { return -1; } ao2_lock(p); other = AST_UNREAL_IS_OUTBOUND(ast, p) ? p->owner : p->chan; if (!other) { ao2_unlock(p); return -1; } ast_channel_ref(other); ao2_unlock(p); ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */ peer = ast_channel_bridge_peer(other); if (peer) { res = ast_channel_queryoption(peer, option, data, datalen, 0); ast_channel_unref(peer); } ast_channel_unref(other); ast_channel_lock(ast); /* Lock back before we leave */ return res; }