Fix queue URL passing (bug #3543)
[asterisk/asterisk.git] / channels / chan_local.c
index 758777a..288a418 100755 (executable)
@@ -139,28 +139,28 @@ 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 /* Not ast_bridged_channel!  Only go one step! */ && 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
                   chance in just a little bit */
-               if (!ast_mutex_trylock(&p->chan->bridge->lock)) {
+               if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
                        if (!ast_mutex_trylock(&p->owner->lock)) {
-                               ast_channel_masquerade(p->owner, p->chan->bridge);
+                               ast_channel_masquerade(p->owner, p->chan->_bridge);
                                p->alreadymasqed = 1;
                                ast_mutex_unlock(&p->owner->lock);
                        }
-                       ast_mutex_unlock(&p->chan->bridge->lock);
+                       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->owner->_bridge)->lock)) {
                        if (!ast_mutex_trylock(&p->chan->lock)) {
-                               ast_channel_masquerade(p->chan, p->owner->bridge);
+                               ast_channel_masquerade(p->chan, p->owner->_bridge);
                                p->alreadymasqed = 1;
                                ast_mutex_unlock(&p->chan->lock);
                        }
-                       ast_mutex_unlock(&p->owner->bridge->lock);
+                       ast_mutex_unlock(&(p->owner->_bridge)->lock);
                }
        }
 }
@@ -233,25 +233,52 @@ 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;
        int res;
        
        ast_mutex_lock(&p->lock);
-       if (p->owner->callerid)
-               p->chan->callerid = strdup(p->owner->callerid);
+       if (p->owner->cid.cid_num)
+               p->chan->cid.cid_num = strdup(p->owner->cid.cid_num);
+       else 
+               p->chan->cid.cid_num = NULL;
+
+       if (p->owner->cid.cid_name)
+               p->chan->cid.cid_name = strdup(p->owner->cid.cid_name);
+       else 
+               p->chan->cid.cid_name = NULL;
+
+       if (p->owner->cid.cid_rdnis)
+               p->chan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis);
        else
-               p->chan->callerid = NULL;
-       if (p->owner->rdnis)
-               p->chan->rdnis = strdup(p->owner->rdnis);
-       else
-               p->chan->rdnis = NULL;
-       if (p->owner->ani)
-               p->chan->ani = strdup(p->owner->ani);
+               p->chan->cid.cid_rdnis = NULL;
+
+       if (p->owner->cid.cid_ani)
+               p->chan->cid.cid_ani = strdup(p->owner->cid.cid_ani);
        else
-               p->chan->ani = NULL;
+               p->chan->cid.cid_ani = NULL;
+
        strncpy(p->chan->language, p->owner->language, sizeof(p->chan->language) - 1);
+       strncpy(p->chan->accountcode, p->owner->accountcode, sizeof(p->chan->accountcode) - 1);
+       p->chan->cdrflags = p->owner->cdrflags;
+       
        p->launchedpbx = 1;
        /* Start switch on sub channel */
        res = ast_pbx_start(p->chan);
@@ -301,6 +328,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;
@@ -324,6 +355,9 @@ static int local_hangup(struct ast_channel *ast)
                        cur = cur->next;
                }
                ast_mutex_unlock(&locallock);
+               /* Grab / release lock just in case */
+               ast_mutex_lock(&p->lock);
+               ast_mutex_unlock(&p->lock);
                /* And destroy */
                if (!glaredetect) {
                        ast_mutex_destroy(&p->lock);
@@ -368,7 +402,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;
@@ -418,6 +452,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;
@@ -438,6 +474,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);
@@ -451,7 +488,7 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
 }
 
 
-static struct ast_channel *local_request(char *type, int format, void *data)
+static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
 {
        struct local_pvt *p;
        struct ast_channel *chan = NULL;