diff options
Diffstat (limited to 'channels/chan_local.c')
-rwxr-xr-x | channels/chan_local.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c index fc8fd8820..bdf8101ec 100755 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -139,7 +139,7 @@ static void check_bridge(struct local_pvt *p, int isoutbound) { if (p->alreadymasqed || p->nooptimization) return; - if (isoutbound && p->chan && p->chan->bridge && p->owner) { + if (isoutbound && p->chan && p->chan->bridge && p->owner && !p->owner->pvt->readq) { /* Masquerade bridged channel into owner */ /* Lock everything we need, one by one, and give up if we can't get everything. Remember, we'll get another @@ -152,7 +152,7 @@ static void check_bridge(struct local_pvt *p, int isoutbound) } ast_mutex_unlock(&p->chan->bridge->lock); } - } else if (!isoutbound && p->owner && p->owner->bridge && p->chan) { + } else if (!isoutbound && p->owner && p->owner->bridge && p->chan && !p->chan->pvt->readq) { /* Masquerade bridged channel into chan */ if (!ast_mutex_trylock(&p->owner->bridge->lock)) { if (!ast_mutex_trylock(&p->chan->lock)) { @@ -177,12 +177,17 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f) int res = -1; int isoutbound; - /* Just queue for delivery to the other side */ ast_mutex_lock(&p->lock); isoutbound = IS_OUTBOUND(ast, p); - res = local_queue_frame(p, isoutbound, f, ast); - check_bridge(p, isoutbound); + if (f && (f->frametype == AST_FRAME_VOICE)) + check_bridge(p, isoutbound); + if (!p->alreadymasqed) + res = local_queue_frame(p, isoutbound, f, ast); + else { + ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name); + res = 0; + } ast_mutex_unlock(&p->lock); return res; } @@ -233,6 +238,22 @@ static int local_digit(struct ast_channel *ast, char digit) return res; } +static int local_sendhtml(struct ast_channel *ast, int subclass, char *data, int datalen) +{ + struct local_pvt *p = ast->pvt->pvt; + int res = -1; + struct ast_frame f = { AST_FRAME_HTML, }; + int isoutbound; + ast_mutex_lock(&p->lock); + isoutbound = IS_OUTBOUND(ast, p); + f.subclass = subclass; + f.data = data; + f.datalen = datalen; + res = local_queue_frame(p, isoutbound, &f, ast); + ast_mutex_unlock(&p->lock); + return res; +} + static int local_call(struct ast_channel *ast, char *dest, int timeout) { struct local_pvt *p = ast->pvt->pvt; @@ -304,6 +325,10 @@ static int local_hangup(struct ast_channel *ast) p->owner = NULL; ast->pvt->pvt = NULL; + ast_mutex_lock(&usecnt_lock); + usecnt--; + ast_mutex_unlock(&usecnt_lock); + if (!p->owner && !p->chan) { /* Okay, done with the private part now, too. */ glaredetect = p->glaredetect; @@ -371,7 +396,7 @@ static struct local_pvt *local_alloc(char *data, int format) strncpy(tmp->context, "default", sizeof(tmp->context) - 1); tmp->reqformat = format; if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) { - ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->context, tmp->exten); + ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context); ast_mutex_destroy(&tmp->lock); free(tmp); tmp = NULL; @@ -421,6 +446,8 @@ static struct ast_channel *local_new(struct local_pvt *p, int state) tmp2->pvt->pvt = p; tmp->pvt->send_digit = local_digit; tmp2->pvt->send_digit = local_digit; + tmp->pvt->send_html = local_sendhtml; + tmp2->pvt->send_html = local_sendhtml; tmp->pvt->call = local_call; tmp2->pvt->call = local_call; tmp->pvt->hangup = local_hangup; @@ -441,6 +468,7 @@ static struct ast_channel *local_new(struct local_pvt *p, int state) p->chan = tmp2; ast_mutex_lock(&usecnt_lock); usecnt++; + usecnt++; ast_mutex_unlock(&usecnt_lock); ast_update_use_count(); strncpy(tmp->context, p->context, sizeof(tmp->context)-1); |