Merged revisions 293530 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r293530 | rmudgett | 2010-11-01 12:29:30 -0500 (Mon, 01 Nov 2010) | 10 lines
  
  Analog 3-way call would not connect all parties if one was using sig_pri.
  
  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/trunk@293531 65c4cc65-6c06-0410-ace0-fbb531ad65f3
10-digiumphones
Richard Mudgett 15 years ago
parent 53149a69df
commit 10cbc4a132

@ -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,

@ -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;

@ -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);

Loading…
Cancel
Save