Fixes CC agents not automatically clearing if T309 clears the original call.
Incoming calls with CC enabled will not automatically clear the CC offer record when the call is aborted by T309 processing. All CC agent FSM's have this problem (PTMP, PTP, and Q.SIG). To reproduce: 1) Place incoming call to Asterisk/libpri 2) Either before or after the call is answered, bring the ISDN link down. 3) T309 processing, T309 timeout, or TEI removal will leave the CC agent FSM in the CC available state. The problem is indicated by the "cc report status" CLI command showing a status of CC offered to caller but it will never timeout. The FSM's can be manually cleared by using the "cc cancel all" or "cc cancel core" CLI commands. JIRA LIBPRI-46 JIRA SWP-2241 git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2079 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
5923df047d
commit
7f55b600e0
@ -25,7 +25,13 @@ FSM CC_PTMP_Agent
|
||||
Action Send_CC_Available(Q931_DISCONNECT);
|
||||
Next_State CC_STATE_AVAILABLE;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Release_LinkID;
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
Stimulus CC_EVENT_CANCEL {
|
||||
Action Release_LinkID;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
@ -45,6 +51,10 @@ FSM CC_PTMP_Agent
|
||||
Action Pass_Up_CC_Request;
|
||||
Next_State CC_STATE_REQUESTED;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Stop_T_RETENTION;
|
||||
Action Start_T_RETENTION;
|
||||
}
|
||||
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
|
||||
Action Send_EraseCallLinkageID;
|
||||
Action Release_LinkID;
|
||||
|
@ -20,7 +20,14 @@ FSM CC_PTMP_Agent
|
||||
Action Send_CC_Available(Q931_DISCONNECT);
|
||||
Next_State CC_STATE_AVAILABLE;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Release_LinkID;
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Action Set_Selfdestruct;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
Stimulus CC_EVENT_CANCEL {
|
||||
Action Release_LinkID;
|
||||
Action Set_Selfdestruct;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
@ -39,6 +46,10 @@ FSM CC_PTMP_Agent
|
||||
Action Stop_T_RETENTION;
|
||||
Next_State CC_STATE_REQUESTED;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Stop_T_RETENTION;
|
||||
Action Start_T_RETENTION;
|
||||
}
|
||||
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
|
||||
Action Send_EraseCallLinkageID;
|
||||
Action Release_LinkID;
|
||||
|
@ -25,6 +25,10 @@ FSM CC_PTP_Agent
|
||||
Action Send_CC_Available(Q931_DISCONNECT);
|
||||
Next_State CC_STATE_AVAILABLE;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
Stimulus CC_EVENT_CANCEL {
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
@ -53,6 +57,10 @@ FSM CC_PTP_Agent
|
||||
Action Stop_T_RETENTION;
|
||||
Next_State CC_STATE_REQUESTED;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Stop_T_RETENTION;
|
||||
Action Start_T_RETENTION;
|
||||
}
|
||||
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Next_State CC_STATE_IDLE;
|
||||
|
@ -20,6 +20,11 @@ FSM CC_PTP_Agent
|
||||
Action Send_CC_Available(Q931_DISCONNECT);
|
||||
Next_State CC_STATE_AVAILABLE;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Action Set_Selfdestruct;
|
||||
Next_State CC_STATE_IDLE;
|
||||
}
|
||||
Stimulus CC_EVENT_CANCEL {
|
||||
Action Set_Selfdestruct;
|
||||
Next_State CC_STATE_IDLE;
|
||||
@ -46,6 +51,10 @@ FSM CC_PTP_Agent
|
||||
Action Stop_T_RETENTION;
|
||||
Next_State CC_STATE_REQUESTED;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Stop_T_RETENTION;
|
||||
Action Start_T_RETENTION;
|
||||
}
|
||||
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Action Stop_T_RETENTION;
|
||||
|
@ -41,6 +41,10 @@ FSM CC_QSIG_Agent
|
||||
Action Send_Call_Proceeding;
|
||||
Next_State CC_STATE_REQUESTED;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Stop_T_RETENTION;
|
||||
Action Start_T_RETENTION;
|
||||
}
|
||||
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Next_State CC_STATE_IDLE;
|
||||
|
@ -34,6 +34,10 @@ FSM CC_QSIG_Agent
|
||||
Action Stop_T_RETENTION;
|
||||
Next_State CC_STATE_REQUESTED;
|
||||
}
|
||||
Stimulus CC_EVENT_INTERNAL_CLEARING {
|
||||
Action Stop_T_RETENTION;
|
||||
Action Start_T_RETENTION;
|
||||
}
|
||||
Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
|
||||
Action Pass_Up_CC_Cancel;
|
||||
Action Stop_T_RETENTION;
|
||||
|
27
pri_cc.c
27
pri_cc.c
@ -2613,6 +2613,9 @@ static const char *pri_cc_fsm_event_str(enum CC_EVENTS event)
|
||||
case CC_EVENT_CANCEL:
|
||||
str = "CC_EVENT_CANCEL";
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
str = "CC_EVENT_INTERNAL_CLEARING";
|
||||
break;
|
||||
case CC_EVENT_SIGNALING_GONE:
|
||||
str = "CC_EVENT_SIGNALING_GONE";
|
||||
break;
|
||||
@ -4351,7 +4354,14 @@ static void pri_cc_fsm_ptmp_agent_pend_avail(struct pri *ctrl, q931_call *call,
|
||||
pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_DISCONNECT);
|
||||
cc_record->state = CC_STATE_AVAILABLE;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_release_link_id(ctrl, cc_record);
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
break;
|
||||
case CC_EVENT_CANCEL:
|
||||
pri_cc_act_release_link_id(ctrl, cc_record);
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
break;
|
||||
@ -4384,6 +4394,10 @@ static void pri_cc_fsm_ptmp_agent_avail(struct pri *ctrl, q931_call *call, struc
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_REQUESTED;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
pri_cc_act_start_t_retention(ctrl, cc_record);
|
||||
break;
|
||||
case CC_EVENT_TIMEOUT_T_RETENTION:
|
||||
pri_cc_act_send_erase_call_linkage_id(ctrl, cc_record);
|
||||
pri_cc_act_release_link_id(ctrl, cc_record);
|
||||
@ -5275,6 +5289,11 @@ static void pri_cc_fsm_ptp_agent_pend_avail(struct pri *ctrl, q931_call *call, s
|
||||
pri_cc_act_send_cc_available(ctrl, cc_record, call, Q931_DISCONNECT);
|
||||
cc_record->state = CC_STATE_AVAILABLE;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
break;
|
||||
case CC_EVENT_CANCEL:
|
||||
pri_cc_act_set_self_destruct(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_IDLE;
|
||||
@ -5315,6 +5334,10 @@ static void pri_cc_fsm_ptp_agent_avail(struct pri *ctrl, q931_call *call, struct
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_REQUESTED;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
pri_cc_act_start_t_retention(ctrl, cc_record);
|
||||
break;
|
||||
case CC_EVENT_TIMEOUT_T_RETENTION:
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
@ -5914,6 +5937,10 @@ static void pri_cc_fsm_qsig_agent_avail(struct pri *ctrl, q931_call *call, struc
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
cc_record->state = CC_STATE_REQUESTED;
|
||||
break;
|
||||
case CC_EVENT_INTERNAL_CLEARING:
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
pri_cc_act_start_t_retention(ctrl, cc_record);
|
||||
break;
|
||||
case CC_EVENT_TIMEOUT_T_RETENTION:
|
||||
pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
|
||||
pri_cc_act_stop_t_retention(ctrl, cc_record);
|
||||
|
@ -664,6 +664,8 @@ enum CC_EVENTS {
|
||||
CC_EVENT_LINK_CANCEL,
|
||||
/*! Tear down CC request from upper layer. */
|
||||
CC_EVENT_CANCEL,
|
||||
/*! Abnormal clearing of original call. (T309 processing/T309 timeout/TEI removal) */
|
||||
CC_EVENT_INTERNAL_CLEARING,
|
||||
/*! Received message indicating tear down of CC signaling link completed. */
|
||||
CC_EVENT_SIGNALING_GONE,
|
||||
/*! Delayed hangup request for the signaling link to allow subcmd events to be passed up. */
|
||||
|
19
q931.c
19
q931.c
@ -8472,22 +8472,31 @@ static int pri_internal_clear(void *data)
|
||||
pri_message(ctrl, "clearing, alive %d, hangupack %d\n", c->alive, c->sendhangupack);
|
||||
}
|
||||
|
||||
if (c->cc.record && c->cc.record->signaling == c) {
|
||||
if (c->cc.record) {
|
||||
if (c->cc.record->signaling == c) {
|
||||
pri_cc_event(ctrl, c, c->cc.record, CC_EVENT_SIGNALING_GONE);
|
||||
} else if (c->cc.record->original_call == c) {
|
||||
pri_cc_event(ctrl, c, c->cc.record, CC_EVENT_INTERNAL_CLEARING);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free resources */
|
||||
if (c->alive) {
|
||||
c->alive = 0;
|
||||
ctrl->ev.e = PRI_EVENT_HANGUP;
|
||||
res = Q931_RES_HAVEEVENT;
|
||||
c->alive = 0;
|
||||
} else if (c->sendhangupack) {
|
||||
res = Q931_RES_HAVEEVENT;
|
||||
ctrl->ev.e = PRI_EVENT_HANGUP_ACK;
|
||||
pri_hangup(ctrl, c, c->cause);
|
||||
ctrl->ev.e = PRI_EVENT_HANGUP_ACK;
|
||||
res = Q931_RES_HAVEEVENT;
|
||||
} else {
|
||||
pri_hangup(ctrl, c, c->cause);
|
||||
if (ctrl->subcmds.counter_subcmd) {
|
||||
q931_fill_facility_event(ctrl, ctrl->link.dummy_call);
|
||||
res = Q931_RES_HAVEEVENT;
|
||||
} else {
|
||||
res = 0;
|
||||
pri_hangup(ctrl, c, c->cause);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
Loading…
Reference in New Issue
Block a user