aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_local.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_local.c')
-rwxr-xr-xchannels/chan_local.c40
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);