aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/chan_dahdi.c8
-rw-r--r--channels/sig_analog.c53
-rw-r--r--channels/sig_analog.h1
3 files changed, 40 insertions, 22 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 8bbf9e97b..b6f91f7c6 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -2246,6 +2246,13 @@ static void my_set_pulsedial(void *pvt, int flag)
p->pulsedial = flag;
}
+static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
+{
+ struct dahdi_pvt *p = pvt;
+
+ p->owner = new_owner;
+}
+
static const char *my_get_orig_dialstring(void *pvt)
{
struct dahdi_pvt *p = pvt;
@@ -3528,6 +3535,7 @@ static struct analog_callback dahdi_analog_callbacks =
.cancel_cidspill = my_cancel_cidspill,
.confmute = my_confmute,
.set_pulsedial = my_set_pulsedial,
+ .set_new_owner = my_set_new_owner,
.get_orig_dialstring = my_get_orig_dialstring,
.set_needringing = my_set_needringing,
.set_polarity = my_set_polarity,
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index 6788b8309..ba6ed45c8 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -412,6 +412,14 @@ static int analog_play_tone(struct analog_pvt *p, enum analog_sub sub, enum anal
return -1;
}
+static void analog_set_new_owner(struct analog_pvt *p, struct ast_channel *new_owner)
+{
+ p->owner = new_owner;
+ if (p->calls->set_new_owner) {
+ p->calls->set_new_owner(p->chan_pvt, new_owner);
+ }
+}
+
static struct ast_channel * analog_new_ast_channel(struct analog_pvt *p, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
{
struct ast_channel *c;
@@ -426,7 +434,7 @@ static struct ast_channel * analog_new_ast_channel(struct analog_pvt *p, int sta
}
p->subs[sub].owner = c;
if (!p->owner) {
- p->owner = c;
+ analog_set_new_owner(p, c);
}
return c;
}
@@ -1290,7 +1298,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
/* Move to the call-wait, but un-own us until they flip back. */
analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
} else {
/* The three way hung up, but we still have a call wait */
ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
@@ -1301,11 +1309,11 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
another call */
ast_debug(1, "Call was complete, setting owner to former third call\n");
analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
} else {
/* This call hasn't been completed yet... Set owner to NULL */
ast_debug(1, "Call was incomplete, setting owner to NULL\n");
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
}
}
} else if (p->subs[ANALOG_SUB_CALLWAIT].allocd) {
@@ -1313,14 +1321,14 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
analog_lock_sub_owner(p, ANALOG_SUB_CALLWAIT);
if (!p->subs[ANALOG_SUB_CALLWAIT].owner) {
/* The call waiting call dissappeared. */
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
break;
}
/* Move to the call-wait and switch back to them. */
analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
if (p->owner->_state != AST_STATE_UP) {
ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
}
@@ -1337,11 +1345,11 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
another call */
ast_debug(1, "Call was complete, setting owner to former third call\n");
analog_set_inthreeway(p, ANALOG_SUB_REAL, 0);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
} else {
/* This call hasn't been completed yet... Set owner to NULL */
ast_debug(1, "Call was incomplete, setting owner to NULL\n");
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
}
}
break;
@@ -1402,7 +1410,7 @@ int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
}
if (!p->subs[ANALOG_SUB_REAL].owner && !p->subs[ANALOG_SUB_CALLWAIT].owner && !p->subs[ANALOG_SUB_THREEWAY].owner) {
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
analog_set_ringtimeout(p, 0);
analog_set_confirmanswer(p, 0);
analog_set_pulsedial(p, 0);
@@ -1512,7 +1520,7 @@ int analog_answer(struct analog_pvt *p, struct ast_channel *ast)
ast_debug(1, "Finally swapping real and threeway\n");
analog_play_tone(p, ANALOG_SUB_THREEWAY, -1);
analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
}
}
@@ -2252,7 +2260,7 @@ static void *__analog_ss_thread(void *data)
}
analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
}
@@ -2264,7 +2272,7 @@ static void *__analog_ss_thread(void *data)
analog_play_tone(p, idx, -1);
analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
ast_hangup(chan);
goto quit;
}
@@ -2744,7 +2752,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
analog_stop_callwait(p);
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
/* Don't start streaming audio yet if the incoming call isn't up yet */
if (p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) {
analog_set_dialing(p, 1);
@@ -2794,7 +2802,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
/* Unlock the 3-way call that we swapped to real-call. */
ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
/* Ring the phone */
analog_ring(p);
} else {
@@ -2817,7 +2825,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
/* Unlock the 3-way call that we swapped to real-call. */
ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
- p->owner = NULL;
+ analog_set_new_owner(p, NULL);
/* Ring the phone */
analog_ring(p);
}
@@ -3064,7 +3072,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
/* Swap to call-wait */
analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_CALLWAIT);
analog_play_tone(p, ANALOG_SUB_REAL, -1);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
ast_debug(1, "Making %s the new owner\n", p->owner->name);
if (p->subs[ANALOG_SUB_REAL].owner->_state == AST_STATE_RINGING) {
ast_setstate(p->subs[ANALOG_SUB_REAL].owner, AST_STATE_UP);
@@ -3149,7 +3157,8 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
if (res) {
ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
}
- p->ss_astchan = p->owner = chan;
+ analog_set_new_owner(p, chan);
+ p->ss_astchan = chan;
if (ast_pthread_create_detached(&threadid, NULL, __analog_ss_thread, p)) {
ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
res = analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
@@ -3191,7 +3200,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
/* Swap back -- we're dropping the real 3-way that isn't finished yet*/
analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
orig_3way_sub = ANALOG_SUB_REAL;
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
}
/* 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);
@@ -3215,13 +3224,13 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
if (ast_bridged_channel(p->subs[orig_3way_sub].owner)) {
ast_queue_control(p->subs[orig_3way_sub].owner, AST_CONTROL_UNHOLD);
}
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
} else {
ast_verb(3, "Dumping incomplete call on %s\n", p->subs[ANALOG_SUB_THREEWAY].owner->name);
analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
orig_3way_sub = ANALOG_SUB_REAL;
ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
if (ast_bridged_channel(p->subs[ANALOG_SUB_REAL].owner)) {
ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
}
@@ -3457,7 +3466,7 @@ struct ast_frame *analog_exception(struct analog_pvt *p, struct ast_channel *ast
if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) &&
(res != ANALOG_EVENT_HOOKCOMPLETE)) {
ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
- p->owner = p->subs[ANALOG_SUB_REAL].owner;
+ analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
if (p->owner && ast != p->owner) {
/*
* Could this even happen?
@@ -3834,7 +3843,7 @@ int analog_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, void
int x;
ast_debug(1, "New owner for channel %d is %s\n", new_pvt->channel, newchan->name);
if (new_pvt->owner == oldchan) {
- new_pvt->owner = newchan;
+ analog_set_new_owner(new_pvt, newchan);
}
for (x = 0; x < 3; x++) {
if (new_pvt->subs[x].owner == oldchan) {
diff --git a/channels/sig_analog.h b/channels/sig_analog.h
index 3c33aebf0..d7b6011a3 100644
--- a/channels/sig_analog.h
+++ b/channels/sig_analog.h
@@ -231,6 +231,7 @@ struct analog_callback {
void (* const cancel_cidspill)(void *pvt);
int (* const confmute)(void *pvt, int mute);
void (* const set_pulsedial)(void *pvt, int flag);
+ void (* const set_new_owner)(void *pvt, struct ast_channel *new_owner);
const char *(* const get_orig_dialstring)(void *pvt);
};