Miscellaneous cleanup before T312 branch merge.

git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2236 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Richard Mudgett 2011-03-01 00:22:38 +00:00
parent a5efd98835
commit afd91f7f31
2 changed files with 50 additions and 44 deletions

View File

@ -1907,7 +1907,7 @@ static unsigned char *enc_ni2_initiate_transfer(struct pri *ctrl, unsigned char
msg.operation = ROSE_NI2_InitiateTransfer; msg.operation = ROSE_NI2_InitiateTransfer;
msg.invoke_id = get_invokeid(ctrl); msg.invoke_id = get_invokeid(ctrl);
/* Let's do the trickery to make sure the flag is correct */ /* Let's do the trickery to make sure the flag is correct */
msg.args.ni2.InitiateTransfer.call_reference = call->cr ^ 0x8000; msg.args.ni2.InitiateTransfer.call_reference = call->cr ^ Q931_CALL_REFERENCE_FLAG;
pos = rose_encode_invoke(ctrl, pos, end, &msg); pos = rose_encode_invoke(ctrl, pos, end, &msg);
return pos; return pos;

92
q931.c
View File

@ -4219,9 +4219,9 @@ static void pri_create_fake_clearing(struct q931_call *c, struct pri *master);
void q931_destroycall(struct pri *ctrl, q931_call *c) void q931_destroycall(struct pri *ctrl, q931_call *c)
{ {
q931_call *cur; struct q931_call *cur;
q931_call *prev; struct q931_call *prev;
q931_call *slave; struct q931_call *slave;
int i; int i;
int slavesleft; int slavesleft;
int slaveidx; int slaveidx;
@ -4243,6 +4243,7 @@ void q931_destroycall(struct pri *ctrl, q931_call *c)
if (cur == c) { if (cur == c) {
slaveidx = -1; slaveidx = -1;
if (slave) { if (slave) {
/* Destroying a slave. */
for (i = 0; i < ARRAY_LEN(cur->subcalls); ++i) { for (i = 0; i < ARRAY_LEN(cur->subcalls); ++i) {
if (cur->subcalls[i] == slave) { if (cur->subcalls[i] == slave) {
if (ctrl->debug & PRI_DEBUG_Q931_STATE) { if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
@ -4333,7 +4334,8 @@ void q931_destroycall(struct pri *ctrl, q931_call *c)
*ctrl->callpool = cur->next; *ctrl->callpool = cur->next;
if (ctrl->debug & PRI_DEBUG_Q931_STATE) if (ctrl->debug & PRI_DEBUG_Q931_STATE)
pri_message(ctrl, pri_message(ctrl,
"NEW_HANGUP DEBUG: Destroying the call, ourstate %s, peerstate %s, hold-state %s\n", "Destroying call %p, ourstate %s, peerstate %s, hold-state %s\n",
cur,
q931_call_state_str(cur->ourcallstate), q931_call_state_str(cur->ourcallstate),
q931_call_state_str(cur->peercallstate), q931_call_state_str(cur->peercallstate),
q931_hold_state_str(cur->hold_state)); q931_hold_state_str(cur->hold_state));
@ -5740,7 +5742,7 @@ static void t303_expiry(void *data)
else else
res = send_message(ctrl, c, Q931_SETUP, setup_ies); res = send_message(ctrl, c, Q931_SETUP, setup_ies);
if (res) { if (res) {
pri_error(c->pri, "Error resending setup message!\n"); pri_error(ctrl, "Error resending setup message!\n");
} }
start_t303(c); start_t303(c);
} else { } else {
@ -6398,7 +6400,7 @@ int q931_send_retrieve_rej(struct pri *ctrl, struct q931_call *call, int cause)
return q931_send_retrieve_rej_msg(ctrl, winner, cause); return q931_send_retrieve_rej_msg(ctrl, winner, cause);
} }
static int pri_internal_clear(void *data); static int pri_internal_clear(struct q931_call *call);
/* Fake RELEASE for NT-PTMP initiated SETUPs w/o response */ /* Fake RELEASE for NT-PTMP initiated SETUPs w/o response */
static void pri_fake_clearing(void *data) static void pri_fake_clearing(void *data)
@ -6413,8 +6415,9 @@ static void pri_fake_clearing(void *data)
*/ */
//c->retranstimer = 0; //c->retranstimer = 0;
c->performing_fake_clearing = 1; c->performing_fake_clearing = 1;
if (pri_internal_clear(c) == Q931_RES_HAVEEVENT) if (pri_internal_clear(c) == Q931_RES_HAVEEVENT) {
ctrl->schedev = 1; ctrl->schedev = 1;
}
} }
static void pri_create_fake_clearing(struct q931_call *c, struct pri *master) static void pri_create_fake_clearing(struct q931_call *c, struct pri *master)
@ -6429,14 +6432,17 @@ static int __q931_hangup(struct pri *ctrl, q931_call *c, int cause)
int release_compl = 0; int release_compl = 0;
int t303_was_running = c->master_call->t303_timer; int t303_was_running = c->master_call->t303_timer;
if (ctrl->debug & PRI_DEBUG_Q931_STATE) if (!ctrl || !c) {
return -1;
}
if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
pri_message(ctrl, pri_message(ctrl,
"NEW_HANGUP DEBUG: Calling q931_hangup, ourstate %s, peerstate %s, hold-state %s\n", DBGHEAD "ourstate %s, peerstate %s, hold-state %s\n", DBGINFO,
q931_call_state_str(c->ourcallstate), q931_call_state_str(c->ourcallstate),
q931_call_state_str(c->peercallstate), q931_call_state_str(c->peercallstate),
q931_hold_state_str(c->master_call->hold_state)); q931_hold_state_str(c->master_call->hold_state));
if (!ctrl || !c) }
return -1;
/* If mandatory IE was missing, insist upon that cause code */ /* If mandatory IE was missing, insist upon that cause code */
if (c->cause == PRI_CAUSE_MANDATORY_IE_MISSING) if (c->cause == PRI_CAUSE_MANDATORY_IE_MISSING)
cause = c->cause; cause = c->cause;
@ -6890,25 +6896,25 @@ static void initiate_hangup_if_needed(struct pri *ctrl, struct q931_call *subcal
static void q931_set_subcall_winner(struct q931_call *subcall) static void q931_set_subcall_winner(struct q931_call *subcall)
{ {
struct q931_call *realcall = subcall->master_call; struct q931_call *master = subcall->master_call;
int i; int i;
/* Set the winner first */ /* Set the winner first */
for (i = 0; ; ++i) { for (i = 0; ; ++i) {
if (ARRAY_LEN(realcall->subcalls) <= i) { if (ARRAY_LEN(master->subcalls) <= i) {
pri_error(subcall->pri, "We should always find the winner in the list!\n"); pri_error(subcall->pri, "We should always find the winner in the list!\n");
return; return;
} }
if (realcall->subcalls[i] == subcall) { if (master->subcalls[i] == subcall) {
realcall->pri_winner = i; master->pri_winner = i;
break; break;
} }
} }
/* Start tear down of calls that were not chosen */ /* Start tear down of calls that were not chosen */
for (i = 0; i < ARRAY_LEN(realcall->subcalls); ++i) { for (i = 0; i < ARRAY_LEN(master->subcalls); ++i) {
if (realcall->subcalls[i] && realcall->subcalls[i] != subcall) { if (master->subcalls[i] && master->subcalls[i] != subcall) {
initiate_hangup_if_needed(realcall->pri, realcall->subcalls[i], initiate_hangup_if_needed(master->pri, master->subcalls[i],
PRI_CAUSE_NONSELECTED_USER_CLEARING); PRI_CAUSE_NONSELECTED_USER_CLEARING);
} }
} }
@ -8266,7 +8272,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
break; break;
} }
/* Do nothing */ /* Do nothing */
/* Also when the STATUS asks for the call of an unexisting reference send RELEASE_COMPL */ /* Also when the STATUS asks for the call of an unexisting reference send RELEASE_COMPLETE */
if ((ctrl->debug & PRI_DEBUG_Q931_ANOMALY) && if ((ctrl->debug & PRI_DEBUG_Q931_ANOMALY) &&
(c->cause != PRI_CAUSE_INTERWORKING)) (c->cause != PRI_CAUSE_INTERWORKING))
pri_error(ctrl, "Received unsolicited status: %s\n", pri_cause2str(c->cause)); pri_error(ctrl, "Received unsolicited status: %s\n", pri_cause2str(c->cause));
@ -8300,20 +8306,19 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
/* Free resources */ /* Free resources */
UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_NULL); UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_NULL);
c->peercallstate = Q931_CALL_STATE_NULL; c->peercallstate = Q931_CALL_STATE_NULL;
/* Free resources */
if (c->alive) { if (c->alive) {
ctrl->ev.e = PRI_EVENT_HANGUP; ctrl->ev.e = PRI_EVENT_HANGUP;
res = Q931_RES_HAVEEVENT;
c->alive = 0; c->alive = 0;
} else if (c->sendhangupack) { } else if (c->sendhangupack) {
res = Q931_RES_HAVEEVENT;
ctrl->ev.e = PRI_EVENT_HANGUP_ACK; ctrl->ev.e = PRI_EVENT_HANGUP_ACK;
pri_hangup(ctrl, c, c->cause); pri_hangup(ctrl, c, c->cause);
} else { } else {
pri_hangup(ctrl, c, c->cause); pri_hangup(ctrl, c, c->cause);
res = 0; return 0;
} }
if (res) return Q931_RES_HAVEEVENT;
return res;
} }
break; break;
case Q931_RELEASE_COMPLETE: case Q931_RELEASE_COMPLETE:
@ -8340,20 +8345,15 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
/* Free resources */ /* Free resources */
if (c->alive) { if (c->alive) {
ctrl->ev.e = PRI_EVENT_HANGUP; ctrl->ev.e = PRI_EVENT_HANGUP;
res = Q931_RES_HAVEEVENT;
c->alive = 0; c->alive = 0;
} else if (c->sendhangupack) { } else if (c->sendhangupack) {
res = Q931_RES_HAVEEVENT;
ctrl->ev.e = PRI_EVENT_HANGUP_ACK; ctrl->ev.e = PRI_EVENT_HANGUP_ACK;
pri_hangup(ctrl, c, c->cause); pri_hangup(ctrl, c, c->cause);
} else } else {
res = 0; pri_hangup(ctrl, c, c->cause);
return 0;
if (res) }
return res; return Q931_RES_HAVEEVENT;
else
pri_hangup(ctrl,c,c->cause);
break;
case Q931_RELEASE: case Q931_RELEASE:
q931_display_subcmd(ctrl, c); q931_display_subcmd(ctrl, c);
c->hangupinitiated = 1; c->hangupinitiated = 1;
@ -8362,6 +8362,10 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
c->cause = PRI_CAUSE_MANDATORY_IE_MISSING; c->cause = PRI_CAUSE_MANDATORY_IE_MISSING;
} }
/*
* Don't send RELEASE_COMPLETE if they sent us RELEASE while we
* were waiting for RELEASE_COMPLETE from them, assume a NULL state.
*/
if (c->ourcallstate == Q931_CALL_STATE_RELEASE_REQUEST) if (c->ourcallstate == Q931_CALL_STATE_RELEASE_REQUEST)
c->peercallstate = Q931_CALL_STATE_NULL; c->peercallstate = Q931_CALL_STATE_NULL;
else { else {
@ -8390,8 +8394,6 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
pri_cc_event(ctrl, c, c->cc.record, CC_EVENT_SIGNALING_GONE); pri_cc_event(ctrl, c, c->cc.record, CC_EVENT_SIGNALING_GONE);
} }
/* Don't send release complete if they send us release
while we sent it, assume a NULL state */
if (c->outboundbroadcast && (c != q931_get_subcall_winner(c->master_call))) { if (c->outboundbroadcast && (c != q931_get_subcall_winner(c->master_call))) {
return pri_hangup(ctrl, c, -1); return pri_hangup(ctrl, c, -1);
} }
@ -8933,9 +8935,8 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
} }
/* Clear a call, although we did not receive any hangup notification. */ /* Clear a call, although we did not receive any hangup notification. */
static int pri_internal_clear(void *data) static int pri_internal_clear(struct q931_call *c)
{ {
struct q931_call *c = data;
struct pri *ctrl = c->pri; struct pri *ctrl = c->pri;
int res; int res;
@ -8974,7 +8975,8 @@ static int pri_internal_clear(void *data)
libpri_copy_string(ctrl->ev.hangup.useruserinfo, c->useruserinfo, sizeof(ctrl->ev.hangup.useruserinfo)); libpri_copy_string(ctrl->ev.hangup.useruserinfo, c->useruserinfo, sizeof(ctrl->ev.hangup.useruserinfo));
if (ctrl->debug & PRI_DEBUG_Q931_STATE) { if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
pri_message(ctrl, "clearing, alive %d, hangupack %d\n", c->alive, c->sendhangupack); pri_message(ctrl, DBGHEAD "alive %d, hangupack %d\n", DBGINFO, c->alive,
c->sendhangupack);
} }
if (c->cc.record) { if (c->cc.record) {
@ -9013,13 +9015,15 @@ static void pri_dl_down_timeout(void *data)
struct q931_call *c = data; struct q931_call *c = data;
struct pri *ctrl = c->pri; struct pri *ctrl = c->pri;
if (ctrl->debug & PRI_DEBUG_Q931_STATE) if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
pri_message(ctrl, "T309 timed out waiting for data link re-establishment\n"); pri_message(ctrl, "T309 timed out waiting for data link re-establishment\n");
}
c->retranstimer = 0; c->retranstimer = 0;
c->cause = PRI_CAUSE_DESTINATION_OUT_OF_ORDER; c->cause = PRI_CAUSE_DESTINATION_OUT_OF_ORDER;
if (pri_internal_clear(c) == Q931_RES_HAVEEVENT) if (pri_internal_clear(c) == Q931_RES_HAVEEVENT) {
ctrl->schedev = 1; ctrl->schedev = 1;
}
} }
/* Handle Layer 2 down event for a non active call. */ /* Handle Layer 2 down event for a non active call. */
@ -9028,13 +9032,15 @@ static void pri_dl_down_cancelcall(void *data)
struct q931_call *c = data; struct q931_call *c = data;
struct pri *ctrl = c->pri; struct pri *ctrl = c->pri;
if (ctrl->debug & PRI_DEBUG_Q931_STATE) if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
pri_message(ctrl, "Cancel call after data link failure\n"); pri_message(ctrl, "Cancel call after data link failure\n");
}
c->retranstimer = 0; c->retranstimer = 0;
c->cause = PRI_CAUSE_DESTINATION_OUT_OF_ORDER; c->cause = PRI_CAUSE_DESTINATION_OUT_OF_ORDER;
if (pri_internal_clear(c) == Q931_RES_HAVEEVENT) if (pri_internal_clear(c) == Q931_RES_HAVEEVENT) {
ctrl->schedev = 1; ctrl->schedev = 1;
}
} }
/*! /*!