[libpri-commits] rmudgett: branch group/ccss r1392 - in /team/group/ccss: ./ doc/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Thu Dec 17 15:53:35 CST 2009
Author: rmudgett
Date: Thu Dec 17 15:53:33 2009
New Revision: 1392
URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1392
Log:
PTP monitor FSM written. Needs testing.
* Added CC PTP monitor FSM pseudo code document files in the doc
directory.
* Changed pri_cc_req() API to not promice a PRI_SUBCMD_CC_REQ_RSP event
if the CC request is cancelled by pri_cc_cancel(). The cc_id is no longer
valid after pri_cc_cancel() anyway.
* Made a call's cc_record and cc_record unlink from each other better.
* Made sure that the FSM indirect action timer is canceled when the FSM
self destructs.
Added:
team/group/ccss/doc/cc_ptp_monitor.fsm (with props)
team/group/ccss/doc/cc_ptp_monitor_flattened.fsm (with props)
Modified:
team/group/ccss/doc/cc_ptmp_monitor.fsm
team/group/ccss/doc/cc_ptmp_monitor_flattened.fsm
team/group/ccss/pri_cc.c
team/group/ccss/pri_facility.c
team/group/ccss/pri_facility.h
team/group/ccss/pri_internal.h
team/group/ccss/q931.c
Modified: team/group/ccss/doc/cc_ptmp_monitor.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_ptmp_monitor.fsm?view=diff&rev=1392&r1=1391&r2=1392
==============================================================================
--- team/group/ccss/doc/cc_ptmp_monitor.fsm (original)
+++ team/group/ccss/doc/cc_ptmp_monitor.fsm Thu Dec 17 15:53:33 2009
@@ -95,8 +95,6 @@
/* We were in the middle of a cc-request when we were asked to cancel. */
Epilog {
Action Stop_T_ACTIVATE;
- /* Claim it was a timeout */
- Action Pass_Up_CC_Req_Rsp_Timeout;
}
Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
/*
Modified: team/group/ccss/doc/cc_ptmp_monitor_flattened.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_ptmp_monitor_flattened.fsm?view=diff&rev=1392&r1=1391&r2=1392
==============================================================================
--- team/group/ccss/doc/cc_ptmp_monitor_flattened.fsm (original)
+++ team/group/ccss/doc/cc_ptmp_monitor_flattened.fsm Thu Dec 17 15:53:33 2009
@@ -111,30 +111,22 @@
*/
Action Send_CC_Deactivate_Req;
Action Stop_T_ACTIVATE;
- /* Claim it was a timeout */
- Action Pass_Up_CC_Req_Rsp_Timeout;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_CC_REQUEST_FAIL {
Action Stop_T_ACTIVATE;
- /* Claim it was a timeout */
- Action Pass_Up_CC_Req_Rsp_Timeout;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
Action Stop_T_ACTIVATE;
- /* Claim it was a timeout */
- Action Pass_Up_CC_Req_Rsp_Timeout;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Stimulus CC_EVENT_LINK_CANCEL {
/* Received CCBSErase */
Action Stop_T_ACTIVATE;
- /* Claim it was a timeout */
- Action Pass_Up_CC_Req_Rsp_Timeout;
Action Set_Selfdestruct;
Next_State CC_STATE_IDLE;
}
Added: team/group/ccss/doc/cc_ptp_monitor.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_ptp_monitor.fsm?view=auto&rev=1392
==============================================================================
--- team/group/ccss/doc/cc_ptp_monitor.fsm (added)
+++ team/group/ccss/doc/cc_ptp_monitor.fsm Thu Dec 17 15:53:33 2009
@@ -1,0 +1,170 @@
+/*
+ * FSM pseudo code used in the design/implementation of the CC PTP monitor.
+ */
+FSM CC_PTP_Monitor
+{
+ State CC_STATE_IDLE {
+ Init {
+ }
+ Prolog {
+ Action Set_Selfdestruct;
+ }
+ Stimulus CC_EVENT_AVAILABLE {
+ /* Received CCBS-T-Aailable */
+ Action Pass_Up_CC_Available;
+ Next_State CC_STATE_AVAILABLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Set_Selfdestruct;
+ }
+ }
+ State CC_STATE_AVAILABLE {
+ /*
+ * The upper layer is responsible for canceling the CC available
+ * offering.
+ */
+ Stimulus CC_EVENT_CC_REQUEST {
+ /*
+ * Before event is posted:
+ * cc_record->is_ccnr is set.
+ * The signaling connection call record is created.
+ */
+ Action Queue_CC_Request;
+ /*
+ * For PTP mode the T_ACTIVATE timer is not defined. However,
+ * we will use it to protect our resources from leaks caused
+ * by the network cable being disconnected.
+ * This timer should be set longer than normal so the
+ * CC records will normally be cleaned up by network activity.
+ */
+ Action Start_T_ACTIVATE;
+ Next_State CC_STATE_REQUESTED;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_REQUESTED {
+ Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
+ /*
+ * Received CCBS-T-Request/CCNR-T-Request response
+ * Before event is posted:
+ * Negotiated CC retention setting saved
+ */
+ Action Pass_Up_CC_Req_Rsp_Success;
+ Action Stop_T_ACTIVATE;
+ Next_State CC_STATE_ACTIVATED;
+ }
+ Stimulus CC_EVENT_CC_REQUEST_FAIL {
+ Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_ACTIVATE;
+ /*
+ * If this request fail comes in with the RELEASE_COMPLETE
+ * message then the post action will never get a chance to
+ * run. It will be aborted because the CC_EVENT_SIGNALING_GONE
+ * will be processed first.
+ */
+ Action Post_HANGUP_SIGNALING;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
+ Action Pass_Up_CC_Req_Rsp_Timeout;
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_ACTIVATE;
+ Action Post_HANGUP_SIGNALING;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Claim it was a timeout */
+ Action Pass_Up_CC_Req_Rsp_Timeout;
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_ACTIVATE;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Stop_T_ACTIVATE;
+ Action Hangup_Signaling_Link;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_WAIT_DESTRUCTION {
+ /*
+ * Delayed disconnect of the signaling link to allow subcmd events
+ * from the signaling link to be passed up.
+ */
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Signaling link cleared. */
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_HANGUP_SIGNALING {
+ Action Hangup_Signaling_Link;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Hangup_Signaling_Link;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_ACTIVATED {
+ Prolog {
+ Action Reset_A_Status;
+ }
+ Stimulus CC_EVENT_REMOTE_USER_FREE {
+ /* Received CCBS_T_RemoteUserFree */
+ Action Pass_Up_Remote_User_Free;
+ Test = Get_A_Status;
+ Test == Busy {
+ Next_State CC_STATE_SUSPENDED;
+ }
+ Next_State CC_STATE_WAIT_CALLBACK;
+ }
+ Stimulus CC_EVENT_SUSPEND {
+ Action Set_A_Status_Busy;
+ }
+ Stimulus CC_EVENT_RESUME {
+ Action Reset_A_Status;
+ }
+ }
+ State CC_STATE_WAIT_CALLBACK {
+ Stimulus CC_EVENT_SUSPEND {
+ Next_State CC_STATE_SUSPENDED;
+ }
+ }
+ State CC_STATE_SUSPENDED {
+ Prolog {
+ Action Send_CC_Suspend;
+ }
+ Stimulus CC_EVENT_RESUME {
+ Action Send_CC_Resume;
+ Next_State CC_STATE_ACTIVATED;
+ }
+ }
+ Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_WAIT_CALLBACK, CC_STATE_SUSPENDED) {
+ Prolog {
+ /* Start T_CCBS6/T_CCNR6 depending upon CC mode. */
+ Action Start_T_SUPERVISION;
+ }
+ Epilog {
+ Action Stop_T_SUPERVISION;
+ }
+ Stimulus CC_EVENT_RECALL {
+ /* The original call parameters have already been set. */
+ Action Queue_SETUP_Recall;
+ }
+ Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
+ Action Pass_Up_CC_Cancel;
+ Action Post_HANGUP_SIGNALING;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Signaling link cleared. */
+ Action Pass_Up_CC_Cancel;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Hangup_Signaling_Link;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+}
Propchange: team/group/ccss/doc/cc_ptp_monitor.fsm
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/ccss/doc/cc_ptp_monitor.fsm
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/group/ccss/doc/cc_ptp_monitor.fsm
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/ccss/doc/cc_ptp_monitor_flattened.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_ptp_monitor_flattened.fsm?view=auto&rev=1392
==============================================================================
--- team/group/ccss/doc/cc_ptp_monitor_flattened.fsm (added)
+++ team/group/ccss/doc/cc_ptp_monitor_flattened.fsm Thu Dec 17 15:53:33 2009
@@ -1,0 +1,213 @@
+/*
+ * FSM pseudo code used in the design/implementation of the CC PTP monitor.
+ */
+FSM CC_PTP_Monitor
+{
+ State CC_STATE_IDLE {
+ Stimulus CC_EVENT_AVAILABLE {
+ /* Received CCBS-T-Aailable */
+ Action Pass_Up_CC_Available;
+ Next_State CC_STATE_AVAILABLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Set_Selfdestruct;
+ }
+ }
+ State CC_STATE_AVAILABLE {
+ /*
+ * The upper layer is responsible for canceling the CC available
+ * offering.
+ */
+ Stimulus CC_EVENT_CC_REQUEST {
+ /*
+ * Before event is posted:
+ * cc_record->is_ccnr is set.
+ * The signaling connection call record is created.
+ */
+ Action Queue_CC_Request;
+ /*
+ * For PTP mode the T_ACTIVATE timer is not defined. However,
+ * we will use it to protect our resources from leaks caused
+ * by the network cable being disconnected.
+ * This timer should be set longer than normal so the
+ * CC records will normally be cleaned up by network activity.
+ */
+ Action Start_T_ACTIVATE;
+ Next_State CC_STATE_REQUESTED;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_REQUESTED {
+ Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
+ /*
+ * Received CCBS-T-Request/CCNR-T-Request response
+ * Before event is posted:
+ * Negotiated CC retention setting saved
+ */
+ Action Pass_Up_CC_Req_Rsp_Success;
+ Action Stop_T_ACTIVATE;
+ /* Start T_CCBS6/T_CCNR6 depending upon CC mode. */
+ Action Start_T_SUPERVISION;
+ Action Reset_A_Status;
+ Next_State CC_STATE_ACTIVATED;
+ }
+ Stimulus CC_EVENT_CC_REQUEST_FAIL {
+ Action Pass_Up_CC_Req_Rsp_Fail(error/reject, code);
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_ACTIVATE;
+ /*
+ * If this request fail comes in with the RELEASE_COMPLETE
+ * message then the post action will never get a chance to
+ * run. It will be aborted because the CC_EVENT_SIGNALING_GONE
+ * will be processed first.
+ */
+ Action Post_HANGUP_SIGNALING;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_TIMEOUT_T_ACTIVATE {
+ Action Pass_Up_CC_Req_Rsp_Timeout;
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_ACTIVATE;
+ Action Post_HANGUP_SIGNALING;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Claim it was a timeout */
+ Action Pass_Up_CC_Req_Rsp_Timeout;
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_ACTIVATE;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Stop_T_ACTIVATE;
+ Action Hangup_Signaling_Link;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_WAIT_DESTRUCTION {
+ /*
+ * Delayed disconnect of the signaling link to allow subcmd events
+ * from the signaling link to be passed up.
+ */
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Signaling link cleared. */
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_HANGUP_SIGNALING {
+ Action Hangup_Signaling_Link;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Hangup_Signaling_Link;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_ACTIVATED {
+ Stimulus CC_EVENT_REMOTE_USER_FREE {
+ /* Received CCBS_T_RemoteUserFree */
+ Action Pass_Up_Remote_User_Free;
+ Test = Get_A_Status;
+ Test == Busy {
+ Action Send_CC_Suspend;
+ Next_State CC_STATE_SUSPENDED;
+ }
+ Next_State CC_STATE_WAIT_CALLBACK;
+ }
+ Stimulus CC_EVENT_SUSPEND {
+ Action Set_A_Status_Busy;
+ }
+ Stimulus CC_EVENT_RESUME {
+ Action Reset_A_Status;
+ }
+ Stimulus CC_EVENT_RECALL {
+ /* The original call parameters have already been set. */
+ Action Queue_SETUP_Recall;
+ }
+ Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
+ Action Pass_Up_CC_Cancel;
+ Action Post_HANGUP_SIGNALING;
+ Action Stop_T_SUPERVISION;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Signaling link cleared. */
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_SUPERVISION;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Hangup_Signaling_Link;
+ Action Stop_T_SUPERVISION;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_WAIT_CALLBACK {
+ Stimulus CC_EVENT_SUSPEND {
+ Action Send_CC_Suspend;
+ Next_State CC_STATE_SUSPENDED;
+ }
+ Stimulus CC_EVENT_RECALL {
+ /* The original call parameters have already been set. */
+ Action Queue_SETUP_Recall;
+ }
+ Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
+ Action Pass_Up_CC_Cancel;
+ Action Post_HANGUP_SIGNALING;
+ Action Stop_T_SUPERVISION;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Signaling link cleared. */
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_SUPERVISION;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Hangup_Signaling_Link;
+ Action Stop_T_SUPERVISION;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+ State CC_STATE_SUSPENDED {
+ Stimulus CC_EVENT_RESUME {
+ Action Send_CC_Resume;
+ Action Reset_A_Status;
+ Next_State CC_STATE_ACTIVATED;
+ }
+ Stimulus CC_EVENT_RECALL {
+ /* The original call parameters have already been set. */
+ Action Queue_SETUP_Recall;
+ }
+ Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
+ Action Pass_Up_CC_Cancel;
+ Action Post_HANGUP_SIGNALING;
+ Action Stop_T_SUPERVISION;
+ Next_State CC_STATE_WAIT_DESTRUCTION;
+ }
+ Stimulus CC_EVENT_SIGNALING_GONE {
+ /* Signaling link cleared. */
+ Action Pass_Up_CC_Cancel;
+ Action Stop_T_SUPERVISION;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ Stimulus CC_EVENT_CANCEL {
+ Action Hangup_Signaling_Link;
+ Action Stop_T_SUPERVISION;
+ Action Set_Selfdestruct;
+ Next_State CC_STATE_IDLE;
+ }
+ }
+}
Propchange: team/group/ccss/doc/cc_ptp_monitor_flattened.fsm
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/ccss/doc/cc_ptp_monitor_flattened.fsm
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/group/ccss/doc/cc_ptp_monitor_flattened.fsm
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/group/ccss/pri_cc.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_cc.c?view=diff&rev=1392&r1=1391&r2=1392
==============================================================================
--- team/group/ccss/pri_cc.c (original)
+++ team/group/ccss/pri_cc.c Thu Dec 17 15:53:33 2009
@@ -253,6 +253,16 @@
struct pri_cc_record **prev;
struct pri_cc_record *current;
+ /* Unlink CC signaling link associations. */
+ if (doomed->original_call) {
+ doomed->original_call->cc.record = NULL;
+ doomed->original_call = NULL;
+ }
+ if (doomed->signaling) {
+ doomed->signaling->cc.record = NULL;
+ doomed->signaling = NULL;
+ }
+
ctrl = PRI_MASTER(ctrl);
for (prev = &ctrl->cc.pool, current = ctrl->cc.pool; current;
prev = ¤t->next, current = current->next) {
@@ -291,6 +301,7 @@
}
/* Initialize the new record */
+ cc_record->master = ctrl;
cc_record->record_id = record_id;
cc_record->call_linkage_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
@@ -729,6 +740,66 @@
/*!
* \internal
+ * \brief Encode ETSI PTP CCBS_T_Request/CCNR_T_Request message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param pos Starting position to encode the facility ie contents.
+ * \param end End of facility ie contents encoding data buffer.
+ * \param cc_record Call completion record to process event.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_etsi_ptp_cc_request(struct pri *ctrl,
+ unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
+{
+ struct rose_msg_invoke msg;
+
+ pos = facility_encode_header(ctrl, pos, end, NULL);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.invoke_id = get_invokeid(ctrl);
+ msg.operation = cc_record->is_ccnr
+ ? ROSE_ETSI_CCNR_T_Request : ROSE_ETSI_CCBS_T_Request;
+
+ if (cc_record->saved_ie_contents.length
+ <= sizeof(msg.args.etsi.CCBS_T_Request.q931ie_contents)) {
+ /* Saved BC, HLC, and LLC from initial SETUP */
+ msg.args.etsi.CCBS_T_Request.q931ie.length = cc_record->saved_ie_contents.length;
+ memcpy(msg.args.etsi.CCBS_T_Request.q931ie.contents,
+ cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
+ } else {
+ pri_error(ctrl, "CCBS_T_Request q931 ie contents did not fit.\n");
+ }
+
+ q931_copy_address_to_rose(ctrl, &msg.args.etsi.CCBS_T_Request.destination,
+ &cc_record->party_b);
+
+ if (cc_record->party_a.number.valid && cc_record->party_a.number.str[0]) {
+ q931_copy_id_address_to_rose(ctrl, &msg.args.etsi.CCBS_T_Request.originating,
+ &cc_record->party_a);
+
+ msg.args.etsi.CCBS_T_Request.presentation_allowed_indicator_present = 1;
+ if ((cc_record->party_a.number.presentation & PRI_PRES_RESTRICTION)
+ == PRI_PRES_ALLOWED) {
+ msg.args.etsi.CCBS_T_Request.presentation_allowed_indicator = 1;
+ }
+ }
+
+ if (cc_record->master->cc.option.retain_service) {
+ msg.args.etsi.CCBS_T_Request.retention_supported = 1;
+ }
+
+ pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+ return pos;
+}
+
+/*!
+ * \internal
* \brief Encode ETSI PTMP CCBSDeactivate message.
*
* \param ctrl D channel controller for diagnostic messages or global options.
@@ -984,7 +1055,7 @@
}
break;
case PRI_SWITCH_QSIG:
- /* \todo BUGBUG rose_remote_user_free_encode(Q.SIG) not written. */
+ /*! \todo BUGBUG rose_remote_user_free_encode(Q.SIG) not written. */
return -1;
default:
return -1;
@@ -1021,6 +1092,148 @@
}
return 0;
+}
+
+/*!
+ * \internal
+ * \brief Encode and queue a CC suspend message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode CC suspend message.
+ * \param msgtype Q.931 message type to put facility ie in.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int rose_cc_suspend_encode(struct pri *ctrl, q931_call *call, int msgtype)
+{
+ unsigned char buffer[256];
+ unsigned char *end;
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ end =
+ enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
+ ROSE_ETSI_CCBS_T_Suspend);
+ break;
+ case PRI_SWITCH_QSIG:
+ /*! \todo BUGBUG rose_cc_suspend_encode(Q.SIG) not written. */
+ return -1;
+ default:
+ return -1;
+ }
+ if (!end) {
+ return -1;
+ }
+
+ return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
+}
+
+/*!
+ * \internal
+ * \brief Encode and send a CC suspend message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param cc_record Call completion record to process event.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int send_cc_suspend(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+ q931_call *call;
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ call = cc_record->signaling;
+ if (!call) {
+ return -1;
+ }
+ if (rose_cc_suspend_encode(ctrl, call, Q931_FACILITY)
+ || q931_facility(ctrl, call)) {
+ pri_message(ctrl, "Could not schedule message for CC suspend.\n");
+ return -1;
+ }
+ return 0;
+ case PRI_SWITCH_QSIG:
+ /*! \todo BUGBUG send_cc_suspend(Q.SIG) not written */
+ return -1;
+ default:
+ return -1;
+ }
+}
+
+/*!
+ * \internal
+ * \brief Encode and queue a CC resume message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode CC resume message.
+ * \param msgtype Q.931 message type to put facility ie in.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int rose_cc_resume_encode(struct pri *ctrl, q931_call *call, int msgtype)
+{
+ unsigned char buffer[256];
+ unsigned char *end;
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ end =
+ enc_etsi_ptp_cc_operation(ctrl, buffer, buffer + sizeof(buffer),
+ ROSE_ETSI_CCBS_T_Resume);
+ break;
+ case PRI_SWITCH_QSIG:
+ /*! \todo BUGBUG rose_cc_resume_encode(Q.SIG) not written. */
+ return -1;
+ default:
+ return -1;
+ }
+ if (!end) {
+ return -1;
+ }
+
+ return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
+}
+
+/*!
+ * \internal
+ * \brief Encode and send a CC resume message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param cc_record Call completion record to process event.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int send_cc_resume(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+ q931_call *call;
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_EUROISDN_E1:
+ case PRI_SWITCH_EUROISDN_T1:
+ call = cc_record->signaling;
+ if (!call) {
+ return -1;
+ }
+ if (rose_cc_resume_encode(ctrl, call, Q931_FACILITY)
+ || q931_facility(ctrl, call)) {
+ pri_message(ctrl, "Could not schedule message for CC resume.\n");
+ return -1;
+ }
+ return 0;
+ case PRI_SWITCH_QSIG:
+ /*! \todo BUGBUG send_cc_resume(Q.SIG) not written */
+ return -1;
+ default:
+ return -1;
+ }
}
/*!
@@ -1433,7 +1646,7 @@
}
/*!
- * \brief Respond to the received CCBSRequest/CCNRRequest invoke message.
+ * \brief Respond to the received PTMP CCBSRequest/CCNRRequest invoke message.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param call Call leg from which the message came.
@@ -1441,7 +1654,7 @@
*
* \return Nothing
*/
-void pri_cc_request(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke)
+void pri_cc_ptmp_request(struct pri *ctrl, q931_call *call, const struct rose_msg_invoke *invoke)
{
struct pri_cc_record *cc_record;
@@ -1589,6 +1802,9 @@
case CC_EVENT_SIGNALING_GONE:
str = "CC_EVENT_SIGNALING_GONE";
break;
+ case CC_EVENT_HANGUP_SIGNALING:
+ str = "CC_EVENT_HANGUP_SIGNALING";
+ break;
case CC_EVENT_MSG_ALERTING:
str = "CC_EVENT_MSG_ALERTING";
break;
@@ -1649,6 +1865,11 @@
static void pri_cc_act_set_self_destruct(struct pri *ctrl, struct pri_cc_record *cc_record)
{
PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
+
+ /* Abort any pending indirect events. */
+ pri_schedule_del(ctrl, cc_record->t_indirect);
+ cc_record->t_indirect = 0;
+
cc_record->fsm_complete = 1;
}
@@ -1698,7 +1919,7 @@
struct pri_cc_record *cc_record = data;
cc_record->t_retention = 0;
- q931_cc_timeout(cc_record->signaling->pri, cc_record->signaling, cc_record,
+ q931_cc_timeout(cc_record->master, cc_record->signaling, cc_record,
CC_EVENT_TIMEOUT_T_RETENTION);
}
@@ -1751,7 +1972,7 @@
struct pri_cc_record *cc_record = data;
cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
- q931_cc_timeout(cc_record->signaling->pri, cc_record->signaling, cc_record,
+ q931_cc_timeout(cc_record->master, cc_record->signaling, cc_record,
CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
}
@@ -1806,7 +2027,7 @@
struct pri_cc_record *cc_record = data;
cc_record->t_supervision = 0;
- q931_cc_timeout(cc_record->signaling->pri, cc_record->signaling, cc_record,
+ q931_cc_timeout(cc_record->master, cc_record->signaling, cc_record,
CC_EVENT_TIMEOUT_T_SUPERVISION);
}
@@ -1887,7 +2108,7 @@
struct pri_cc_record *cc_record = data;
cc_record->fsm.ptmp.t_ccbs3 = 0;
- q931_cc_timeout(cc_record->signaling->pri, cc_record->signaling, cc_record,
+ q931_cc_timeout(cc_record->master, cc_record->signaling, cc_record,
CC_EVENT_TIMEOUT_T_CCBS3);
}
@@ -2137,6 +2358,57 @@
cc_record->ccbs_reference_id =
msg->result->args.etsi.CCBSRequest.ccbs_reference & 0x7F;
cc_record->option.recall_mode = msg->result->args.etsi.CCBSRequest.recall_mode;
+
+ pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_ACCEPT);
+ break;
+ case APDU_CALLBACK_REASON_MSG_ERROR:
+ cc_record->msg.cc_req_rsp.reason = reason;
+ cc_record->msg.cc_req_rsp.code = msg->error->code;
+
+ pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
+ break;
+ case APDU_CALLBACK_REASON_MSG_REJECT:
+ cc_record->msg.cc_req_rsp.reason = reason;
+ cc_record->msg.cc_req_rsp.code = msg->reject->code;
+
+ pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_FAIL);
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * No more reponses are really expected.
+ * However, the FSM will be removing the apdu_event itself instead.
+ */
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief cc-request PTP response callback function.
+ *
+ * \param reason Reason callback is called.
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param apdu APDU queued entry. Do not change!
+ * \param msg APDU response message data. (NULL if was not the reason called.)
+ *
+ * \return TRUE if no more responses are expected.
+ */
+static int pri_cc_req_response_ptp(enum APDU_CALLBACK_REASON reason, struct pri *ctrl, struct q931_call *call, struct apdu_event *apdu, const union apdu_msg_data *msg)
+{
+ struct pri_cc_record *cc_record;
+
+ cc_record = apdu->response.user.ptr;
+
+ switch (reason) {
+ case APDU_CALLBACK_REASON_TIMEOUT:
+ pri_cc_event(ctrl, call, cc_record, CC_EVENT_TIMEOUT_T_ACTIVATE);
+ break;
+ case APDU_CALLBACK_REASON_MSG_RESULT:
+ cc_record->option.retain_service =
+ msg->result->args.etsi.CCBS_T_Request.retention_supported;
pri_cc_event(ctrl, call, cc_record, CC_EVENT_CC_REQUEST_ACCEPT);
break;
@@ -2193,15 +2465,15 @@
msgtype = Q931_FACILITY;
response.callback = pri_cc_req_response_ptmp;
} else {
- /* \todo BUGBUG rose_cc_request(PTP) not written. */
- //msgtype = Q931_REGISTER;
- //response.callback = pri_cc_req_response_ptp;
- return -1;
+ end =
+ enc_etsi_ptp_cc_request(ctrl, buffer, buffer + sizeof(buffer), cc_record);
+ msgtype = Q931_REGISTER;
+ response.callback = pri_cc_req_response_ptp;
}
response.timeout_time = ctrl->timers[PRI_TIMER_T_ACTIVATE];
break;
case PRI_SWITCH_QSIG:
- /* \todo BUGBUG rose_cc_request(Q.SIG) not written. */
+ /*! \todo BUGBUG rose_cc_request(Q.SIG) not written. */
//msgtype = Q931_SETUP;
//response.callback = pri_cc_req_response_qsig;
//response.timeout_time = ctrl->timers[PRI_TIMER_QSIG_CC_T1];
@@ -2280,6 +2552,36 @@
{
PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
send_remote_user_free(ctrl, cc_record->signaling, cc_record);
+}
+
+/*!
+ * \internal
+ * \brief FSM action to send the CC suspend message.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_record Call completion record to process event.
+ *
+ * \return Nothing
+ */
+static void pri_cc_act_send_cc_suspend(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+ PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
+ send_cc_suspend(ctrl, cc_record);
+}
+
+/*!
+ * \internal
+ * \brief FSM action to send the CC resume message.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_record Call completion record to process event.
+ *
+ * \return Nothing
+ */
+static void pri_cc_act_send_cc_resume(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+ PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
+ send_cc_resume(ctrl, cc_record);
}
/*!
@@ -2402,7 +2704,8 @@
{
struct pri_cc_record *cc_record = data;
- q931_cc_indirect(cc_record->signaling->pri, cc_record->signaling, cc_record,
+ cc_record->t_indirect = 0;
+ q931_cc_indirect(cc_record->master, cc_record->signaling, cc_record,
pri_cc_fill_status_rsp_a);
}
@@ -2424,7 +2727,12 @@
PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
if (cc_record->fsm.ptmp.party_a_status_acc != CC_PARTY_A_AVAILABILITY_INVALID) {
/* Accumulated party A status is not invalid so pass it up. */
- pri_schedule_event(ctrl, 0, pri_cc_indirect_status_rsp_a, cc_record);
+ if (cc_record->t_indirect) {
+ pri_error(ctrl, "!! An indirect action is already active!");
+ pri_schedule_del(ctrl, cc_record->t_indirect);
+ }
+ cc_record->t_indirect = pri_schedule_event(ctrl, 0, pri_cc_indirect_status_rsp_a,
+ cc_record);
}
}
@@ -2471,6 +2779,21 @@
{
PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
cc_record->party_a_status = CC_PARTY_A_AVAILABILITY_INVALID;
+}
+
+/*!
+ * \internal
+ * \brief FSM action to set A status as busy.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_record Call completion record to process event.
+ *
+ * \return Nothing
+ */
+static void pri_cc_act_set_a_status_busy(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+ PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
+ cc_record->party_a_status = CC_PARTY_A_AVAILABILITY_BUSY;
}
/*!
@@ -2803,6 +3126,58 @@
{
PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
call->cc.hangup_call = 1;
+}
+
+/*!
+ * \internal
+ * \brief Post the CC_EVENT_HANGUP_SIGNALING event (timeout action).
+ *
+ * \param data CC record pointer.
+ *
+ * \return Nothing
+ */
+static void pri_cc_post_hangup_signaling(void *data)
+{
+ struct pri_cc_record *cc_record = data;
+
+ cc_record->t_indirect = 0;
+ q931_cc_timeout(cc_record->master, cc_record->signaling, cc_record,
+ CC_EVENT_HANGUP_SIGNALING);
+}
+
+/*!
+ * \internal
+ * \brief FSM action to post the CC_EVENT_HANGUP_SIGNALING event indirectly.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_record Call completion record to process event.
+ *
+ * \return Nothing
+ */
+static void pri_cc_act_post_hangup_signaling(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+ PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
+ if (cc_record->t_indirect) {
+ pri_error(ctrl, "!! An indirect action is already active!");
+ pri_schedule_del(ctrl, cc_record->t_indirect);
+ }
+ cc_record->t_indirect = pri_schedule_event(ctrl, 0, pri_cc_post_hangup_signaling,
+ cc_record);
+}
+
+/*!
+ * \internal
+ * \brief FSM action to immediately hangup the signaling link.
+ *
+ * \param ctrl D channel controller.
+ * \param cc_record Call completion record to process event.
+ *
+ * \return Nothing
+ */
+static void pri_cc_act_hangup_signaling_link(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+ PRI_CC_ACT_DEBUG_OUTPUT(ctrl);
+ pri_hangup(ctrl, cc_record->signaling, -1);
}
/*!
@@ -3563,30 +3938,22 @@
*/
pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
pri_cc_act_stop_t_activate(ctrl, cc_record);
- /* Claim it was a timeout */
- pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
pri_cc_act_set_self_destruct(ctrl, cc_record);
cc_record->state = CC_STATE_IDLE;
break;
case CC_EVENT_CC_REQUEST_FAIL:
pri_cc_act_stop_t_activate(ctrl, cc_record);
- /* Claim it was a timeout */
- pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
pri_cc_act_set_self_destruct(ctrl, cc_record);
cc_record->state = CC_STATE_IDLE;
break;
case CC_EVENT_TIMEOUT_T_ACTIVATE:
pri_cc_act_stop_t_activate(ctrl, cc_record);
- /* Claim it was a timeout */
- pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
pri_cc_act_set_self_destruct(ctrl, cc_record);
cc_record->state = CC_STATE_IDLE;
break;
case CC_EVENT_LINK_CANCEL:
/* Received CCBSErase */
pri_cc_act_stop_t_activate(ctrl, cc_record);
- /* Claim it was a timeout */
- pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
pri_cc_act_set_self_destruct(ctrl, cc_record);
cc_record->state = CC_STATE_IDLE;
break;
@@ -3640,6 +4007,329 @@
break;
case CC_EVENT_CANCEL:
pri_cc_act_send_cc_deactivate_req(ctrl, cc_record);
+ pri_cc_act_stop_t_supervision(ctrl, cc_record);
+ pri_cc_act_set_self_destruct(ctrl, cc_record);
+ cc_record->state = CC_STATE_IDLE;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * \internal
+ * \brief CC FSM PTP monitor CC_STATE_IDLE.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param cc_record Call completion record to process event.
+ * \param event Event to process.
+ *
+ * \return Nothing
+ */
+static void pri_cc_fsm_ptp_monitor_idle(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
+{
+ switch (event) {
+ case CC_EVENT_AVAILABLE:
+ /* Received CCBS-T-Aailable */
+ pri_cc_act_pass_up_cc_available(ctrl, cc_record);
+ cc_record->state = CC_STATE_AVAILABLE;
+ break;
+ case CC_EVENT_CANCEL:
+ pri_cc_act_set_self_destruct(ctrl, cc_record);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * \internal
+ * \brief CC FSM PTP monitor CC_STATE_AVAILABLE.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param cc_record Call completion record to process event.
+ * \param event Event to process.
+ *
+ * \return Nothing
+ */
+static void pri_cc_fsm_ptp_monitor_avail(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
+{
+ /* The upper layer is responsible for canceling the CC available offering. */
+ switch (event) {
+ case CC_EVENT_CC_REQUEST:
+ /*
+ * Before event is posted:
+ * cc_record->is_ccnr is set.
+ * The signaling connection call record is created.
+ */
+ pri_cc_act_queue_cc_request(ctrl, call, cc_record);
+ /*
+ * For PTP mode the T_ACTIVATE timer is not defined. However,
+ * we will use it to protect our resources from leaks caused
+ * by the network cable being disconnected.
+ * This timer should be set longer than normal so the
+ * CC records will normally be cleaned up by network activity.
+ */
+ //pri_cc_act_start_t_activate(ctrl, cc_record);
+ cc_record->state = CC_STATE_REQUESTED;
+ break;
+ case CC_EVENT_CANCEL:
+ pri_cc_act_set_self_destruct(ctrl, cc_record);
+ cc_record->state = CC_STATE_IDLE;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * \internal
+ * \brief CC FSM PTP monitor CC_STATE_REQUESTED.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param cc_record Call completion record to process event.
+ * \param event Event to process.
+ *
+ * \return Nothing
+ */
+static void pri_cc_fsm_ptp_monitor_req(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
+{
+ switch (event) {
+ case CC_EVENT_CC_REQUEST_ACCEPT:
+ /*
+ * Received CCBS-T-Request/CCNR-T-Request response
+ * Before event is posted:
+ * Negotiated CC retention setting saved
+ */
+ pri_cc_act_pass_up_cc_req_rsp_success(ctrl, cc_record);
+ pri_cc_act_stop_t_activate(ctrl, cc_record);
+ /* Start T_CCBS6/T_CCNR6 depending upon CC mode. */
+ pri_cc_act_start_t_supervision(ctrl, cc_record);
+ pri_cc_act_reset_a_status(ctrl, cc_record);
+ cc_record->state = CC_STATE_ACTIVATED;
+ break;
+ case CC_EVENT_CC_REQUEST_FAIL:
+ pri_cc_act_pass_up_cc_req_rsp_fail(ctrl, cc_record);
+ pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
+ pri_cc_act_stop_t_activate(ctrl, cc_record);
+ /*
+ * If this request fail comes in with the RELEASE_COMPLETE
+ * message then the post action will never get a chance to
+ * run. It will be aborted because the CC_EVENT_SIGNALING_GONE
+ * will be processed first.
+ */
+ pri_cc_act_post_hangup_signaling(ctrl, cc_record);
+ cc_record->state = CC_STATE_WAIT_DESTRUCTION;
+ break;
+ case CC_EVENT_TIMEOUT_T_ACTIVATE:
+ pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
+ pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
+ pri_cc_act_stop_t_activate(ctrl, cc_record);
+ pri_cc_act_post_hangup_signaling(ctrl, cc_record);
+ cc_record->state = CC_STATE_WAIT_DESTRUCTION;
+ break;
+ case CC_EVENT_SIGNALING_GONE:
+ /* Claim it was a timeout */
+ pri_cc_act_pass_up_cc_req_rsp_timeout(ctrl, cc_record);
+ pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
+ pri_cc_act_stop_t_activate(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_stop_t_activate(ctrl, cc_record);
+ pri_cc_act_hangup_signaling_link(ctrl, cc_record);
+ pri_cc_act_set_self_destruct(ctrl, cc_record);
+ cc_record->state = CC_STATE_IDLE;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * \internal
+ * \brief CC FSM PTP monitor CC_STATE_WAIT_DESTRUCTION.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param cc_record Call completion record to process event.
+ * \param event Event to process.
+ *
+ * \return Nothing
+ */
+static void pri_cc_fsm_ptp_monitor_wait_destruction(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
+{
+ /*
+ * Delayed disconnect of the signaling link to allow subcmd events
+ * from the signaling link to be passed up.
+ */
+ switch (event) {
+ case CC_EVENT_SIGNALING_GONE:
+ /* Signaling link cleared. */
+ pri_cc_act_set_self_destruct(ctrl, cc_record);
+ cc_record->state = CC_STATE_IDLE;
+ break;
+ case CC_EVENT_HANGUP_SIGNALING:
+ pri_cc_act_hangup_signaling_link(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_hangup_signaling_link(ctrl, cc_record);
+ pri_cc_act_set_self_destruct(ctrl, cc_record);
+ cc_record->state = CC_STATE_IDLE;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * \internal
+ * \brief CC FSM PTP monitor CC_STATE_ACTIVATED.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param cc_record Call completion record to process event.
+ * \param event Event to process.
+ *
+ * \return Nothing
+ */
+static void pri_cc_fsm_ptp_monitor_activated(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, enum CC_EVENTS event)
+{
+ switch (event) {
+ case CC_EVENT_REMOTE_USER_FREE:
+ /* Received CCBS_T_RemoteUserFree */
+ pri_cc_act_pass_up_remote_user_free(ctrl, cc_record);
+ if (cc_record->party_a_status == CC_PARTY_A_AVAILABILITY_BUSY) {
+ pri_cc_act_send_cc_suspend(ctrl, cc_record);
+ cc_record->state = CC_STATE_SUSPENDED;
+ } else {
+ cc_record->state = CC_STATE_WAIT_CALLBACK;
+ }
+ break;
+ case CC_EVENT_SUSPEND:
+ pri_cc_act_set_a_status_busy(ctrl, cc_record);
+ break;
+ case CC_EVENT_RESUME:
+ pri_cc_act_reset_a_status(ctrl, cc_record);
+ break;
+ case CC_EVENT_RECALL:
+ /* The original call parameters have already been set. */
+ pri_cc_act_queue_setup_recall(ctrl, call, cc_record);
+ break;
+ case CC_EVENT_TIMEOUT_T_SUPERVISION:
+ pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
+ pri_cc_act_post_hangup_signaling(ctrl, cc_record);
+ pri_cc_act_stop_t_supervision(ctrl, cc_record);
+ cc_record->state = CC_STATE_WAIT_DESTRUCTION;
+ break;
+ case CC_EVENT_SIGNALING_GONE:
+ /* Signaling link cleared. */
+ pri_cc_act_pass_up_cc_cancel(ctrl, cc_record);
+ pri_cc_act_stop_t_supervision(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_hangup_signaling_link(ctrl, cc_record);
+ pri_cc_act_stop_t_supervision(ctrl, cc_record);
+ pri_cc_act_set_self_destruct(ctrl, cc_record);
+ cc_record->state = CC_STATE_IDLE;
+ break;
+ default:
+ break;
+ }
+}
+
[... 484 lines stripped ...]
More information about the libpri-commits
mailing list