]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Analog 3-way call would not connect all parties if one was using sig_pri.
authorRichard Mudgett <rmudgett@digium.com>
Mon, 1 Nov 2010 17:29:30 +0000 (17:29 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 1 Nov 2010 17:29:30 +0000 (17:29 +0000)
Also the "dahdi show channel" would not show the correct 3-way call
status.

* Synchronized the inthreeway flag between chan_dahdi and sig_analog.

* Fixed a my_set_linear_mode() sign error and made take an analog sub
channel enum.

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@293530 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_dahdi.c
channels/sig_analog.c
channels/sig_analog.h

index 9952982408f9e9a1d48390c187fd429060ba1840..5ad97dfe719a86273dcf2df1c8e17ede478dd3ba 100644 (file)
@@ -2068,19 +2068,26 @@ static void my_deadlock_avoidance_private(void *pvt)
 /* linear_mode = 0 - turn linear mode off, >0 - turn linear mode on
 *      returns the last value of the linear setting 
 */ 
-static int my_set_linear_mode(void *pvt, int idx, int linear_mode)
+static int my_set_linear_mode(void *pvt, enum analog_sub sub, int linear_mode)
 {
        struct dahdi_pvt *p = pvt;
        int oldval;
+       int idx = analogsub_to_dahdisub(sub);
        
-    if (0 > linear_mode || !dahdi_setlinear(p->subs[idx].dfd, linear_mode)) {
-        return -1;
-    }
+       dahdi_setlinear(p->subs[idx].dfd, linear_mode);
        oldval = p->subs[idx].linear;
-       p->subs[idx].linear = linear_mode;
+       p->subs[idx].linear = linear_mode ? 1 : 0;
        return oldval;
 }
 
+static void my_set_inthreeway(void *pvt, enum analog_sub sub, int inthreeway)
+{
+       struct dahdi_pvt *p = pvt;
+       int idx = analogsub_to_dahdisub(sub);
+
+       p->subs[idx].inthreeway = inthreeway;
+}
+
 static int get_alarms(struct dahdi_pvt *p);
 static void handle_alarms(struct dahdi_pvt *p, int alms);
 static void my_get_and_handle_alarms(void *pvt)
@@ -2382,24 +2389,27 @@ static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel
        struct dahdi_pvt *p = pvt;
        int da, db;
        int tchan;
+       int tinthreeway;
 
        da = analogsub_to_dahdisub(a);
        db = analogsub_to_dahdisub(b);
 
        tchan = p->subs[da].chan;
-
        p->subs[da].chan = p->subs[db].chan;
-
        p->subs[db].chan = tchan;
 
+       tinthreeway = p->subs[da].inthreeway;
+       p->subs[da].inthreeway = p->subs[db].inthreeway;
+       p->subs[db].inthreeway = tinthreeway;
+
+       p->subs[da].owner = ast_a;
+       p->subs[db].owner = ast_b;
+
        if (ast_a)
                ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
        if (ast_b)
                ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
 
-       p->subs[da].owner = ast_a;
-       p->subs[db].owner = ast_b;
-
        wakeup_sub(p, a);
        wakeup_sub(p, b);
 
@@ -3503,6 +3513,7 @@ static struct analog_callback dahdi_analog_callbacks =
        .decrease_ss_count = my_decrease_ss_count,
        .distinctive_ring = my_distinctive_ring,
        .set_linear_mode = my_set_linear_mode,
+       .set_inthreeway = my_set_inthreeway,
        .get_and_handle_alarms = my_get_and_handle_alarms,
        .get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
        .get_sub_fd = my_get_sub_fd,
index 1d68889be03d8a6c4fe35a43d5003ebe07a6ae52..546a56069684a6fb88f092cf290eff987cddc990 100644 (file)
@@ -322,12 +322,11 @@ static void analog_swap_subs(struct analog_pvt *p, enum analog_sub a, enum analo
        ast_debug(1, "Swapping %d and %d\n", a, b);
 
        towner = p->subs[a].owner;
-       tinthreeway = p->subs[a].inthreeway;
-
        p->subs[a].owner = p->subs[b].owner;
-       p->subs[a].inthreeway = p->subs[b].inthreeway;
-
        p->subs[b].owner = towner;
+
+       tinthreeway = p->subs[a].inthreeway;
+       p->subs[a].inthreeway = p->subs[b].inthreeway;
        p->subs[b].inthreeway = tinthreeway;
 
        if (p->calls->swap_subs) {
@@ -954,15 +953,23 @@ static void analog_set_pulsedial(struct analog_pvt *p, int flag)
        p->calls->set_pulsedial(p->chan_pvt, flag);
 }
 
-static int analog_set_linear_mode(struct analog_pvt *p, int index, int linear_mode)
+static int analog_set_linear_mode(struct analog_pvt *p, enum analog_sub sub, int linear_mode)
 {
        if (p->calls->set_linear_mode) {
                /* Return provides old linear_mode setting or error indication */
-               return p->calls->set_linear_mode(p->chan_pvt, index, linear_mode);
+               return p->calls->set_linear_mode(p->chan_pvt, sub, linear_mode);
        }
        return -1;
 }
 
+static void analog_set_inthreeway(struct analog_pvt *p, enum analog_sub sub, int inthreeway)
+{
+       p->subs[sub].inthreeway = inthreeway;
+       if (p->calls->set_inthreeway) {
+               p->calls->set_inthreeway(p->chan_pvt, sub, inthreeway);
+       }
+}
+
 int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout)
 {
        int res, index,mysig;
@@ -1283,7 +1290,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
                                                /* This was part of a three way call.  Immediately make way for
                                                   another call */
                                                ast_debug(1, "Call was complete, setting owner to former third call\n");
-                                               p->subs[ANALOG_SUB_REAL].inthreeway = 0;
+                                               analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
                                                p->owner = p->subs[ANALOG_SUB_REAL].owner;
                                        } else {
                                                /* This call hasn't been completed yet...  Set owner to NULL */
@@ -1319,7 +1326,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
                                        /* This was part of a three way call.  Immediately make way for
                                           another call */
                                        ast_debug(1, "Call was complete, setting owner to former third call\n");
-                                       p->subs[ANALOG_SUB_REAL].inthreeway = 0;
+                                       analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
                                        p->owner = p->subs[ANALOG_SUB_REAL].owner;
                                } else {
                                        /* This call hasn't been completed yet...  Set owner to NULL */
@@ -1341,7 +1348,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
                                                S_OR(p->mohsuggest, NULL),
                                                !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
                                }
-                               p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
+                               analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
                                /* Make it the call wait now */
                                analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_THREEWAY);
                                analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
@@ -1359,7 +1366,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
                        if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
                                /* The other party of the three way call is currently in a call-wait state.
                                   Start music on hold for them, and take the main guy out of the third call */
-                               p->subs[ANALOG_SUB_CALLWAIT].inthreeway = 0;
+                               analog_set_inthreeway(p, ANALOG_SUB_CALLWAIT, 0);
                                if (p->subs[ANALOG_SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[ANALOG_SUB_CALLWAIT].owner)) {
                                        ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
                                                S_OR(p->mohsuggest, NULL),
@@ -1369,7 +1376,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
                        if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
                                ast_channel_unlock(p->subs[ANALOG_SUB_CALLWAIT].owner);
                        }
-                       p->subs[ANALOG_SUB_REAL].inthreeway = 0;
+                       analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
                        /* If this was part of a three way call index, let us make
                           another three way call */
                        analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
@@ -2748,16 +2755,16 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
                                                                        ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
                                                                } else if (res) {
                                                                        /* this isn't a threeway call anymore */
-                                                                       p->subs[ANALOG_SUB_REAL].inthreeway = 0;
-                                                                       p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
+                                                                       analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
+                                                                       analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
 
                                                                        /* Don't actually hang up at this point */
                                                                        break;
                                                                }
                                                        }
                                                        /* this isn't a threeway call anymore */
-                                                       p->subs[ANALOG_SUB_REAL].inthreeway = 0;
-                                                       p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
+                                                       analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
+                                                       analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
                                                } else {
                                                        ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
                                                        ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
@@ -3154,16 +3161,16 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
                                        /* Drop the last call and stop the conference */
                                        ast_verb(3, "Dropping three-way call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name);
                                        ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
-                                       p->subs[ANALOG_SUB_REAL].inthreeway = 0;
-                                       p->subs[ANALOG_SUB_THREEWAY].inthreeway = 0;
+                                       analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
+                                       analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
                                } else {
                                        /* Lets see what we're up to */
                                        if (((ast->pbx) || (ast->_state == AST_STATE_UP)) &&
                                                (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
                                                ast_verb(3, "Building conference on call on %s and %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name, p->subs[ANALOG_SUB_REAL].owner->name);
                                                /* Put them in the threeway, and flip */
-                                               p->subs[ANALOG_SUB_THREEWAY].inthreeway = 1;
-                                               p->subs[ANALOG_SUB_REAL].inthreeway = 1;
+                                               analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 1);
+                                               analog_set_inthreeway(p, ANALOG_SUB_REAL, 1);
                                                if (ast->_state == AST_STATE_UP) {
                                                        analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
                                                        orig_3way_sub = ANALOG_SUB_REAL;
index c1b611527f5403f8ddfea11b1fd28813beca1f9b..b58b0985ae27ae9216383201fb979345e3d6eb69 100644 (file)
@@ -213,7 +213,8 @@ struct analog_callback {
 
        int (* const distinctive_ring)(struct ast_channel *chan, void *pvt, int idx, int *ringdata);
        /* Sets the specified sub-channel in and out of signed linear mode, returns the value that was overwritten */
-       int (* const set_linear_mode)(void *pvt, int idx, int linear_mode);
+       int (* const set_linear_mode)(void *pvt, enum analog_sub sub, int linear_mode);
+       void (* const set_inthreeway)(void *pvt, enum analog_sub sub, int inthreeway);
        void (* const get_and_handle_alarms)(void *pvt);
        void * (* const get_sigpvt_bridged_channel)(struct ast_channel *chan);
        int (* const get_sub_fd)(void *pvt, enum analog_sub sub);