[libpri-commits] rmudgett: branch group/ccss r1398 - in /team/group/ccss: ./ doc/

SVN commits to the libpri project libpri-commits at lists.digium.com
Wed Dec 23 13:13:55 CST 2009


Author: rmudgett
Date: Wed Dec 23 13:13:53 2009
New Revision: 1398

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1398
Log:
Add more Q.SIG CC support code.

*  Reworked q931_cc_timeout() and q931_cc_indirect() to always pass up any
CC events using the dummy call reference call.  As a result CC FSM
timeouts do not need to use the pri_cc_act_post_hangup_signaling() method.
This change eliminated the need for CC_STATE_WAIT_DESTRUCTION in the ETSI
PTP agent FSM.

Modified:
    team/group/ccss/doc/cc_ptp_agent.fsm
    team/group/ccss/doc/cc_ptp_agent_flattened.fsm
    team/group/ccss/doc/cc_ptp_monitor.fsm
    team/group/ccss/doc/cc_ptp_monitor_flattened.fsm
    team/group/ccss/doc/cc_qsig_agent.fsm
    team/group/ccss/doc/cc_qsig_agent_flattened.fsm
    team/group/ccss/doc/cc_qsig_monitor.fsm
    team/group/ccss/doc/cc_qsig_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_ptp_agent.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_ptp_agent.fsm?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_ptp_agent.fsm (original)
+++ team/group/ccss/doc/cc_ptp_agent.fsm Wed Dec 23 13:13:53 2009
@@ -75,24 +75,6 @@
 			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;
@@ -146,8 +128,8 @@
 		}
 		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
 			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Hangup_Signaling_Link;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */

Modified: team/group/ccss/doc/cc_ptp_agent_flattened.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_ptp_agent_flattened.fsm?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_ptp_agent_flattened.fsm (original)
+++ team/group/ccss/doc/cc_ptp_agent_flattened.fsm Wed Dec 23 13:13:53 2009
@@ -77,27 +77,6 @@
 			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 {
 			Action Pass_Up_A_Status;
@@ -123,9 +102,10 @@
 		}
 		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
 			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
+			Action Hangup_Signaling_Link;
 			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -155,9 +135,10 @@
 		}
 		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
 			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
+			Action Hangup_Signaling_Link;
 			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -188,9 +169,10 @@
 		}
 		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
 			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
+			Action Hangup_Signaling_Link;
 			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */

Modified: team/group/ccss/doc/cc_ptp_monitor.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_ptp_monitor.fsm?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_ptp_monitor.fsm (original)
+++ team/group/ccss/doc/cc_ptp_monitor.fsm Wed Dec 23 13:13:53 2009
@@ -45,6 +45,9 @@
 		}
 	}
 	State CC_STATE_REQUESTED {
+		Epilog {
+			Action Stop_T_ACTIVATE;
+		}
 		Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
 			/*
 			 * Received CCBS-T-Request/CCNR-T-Request response
@@ -52,13 +55,11 @@
 			 *   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
@@ -71,19 +72,16 @@
 		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;
+			Action Hangup_Signaling_Link;
+			Next_State CC_STATE_IDLE;
 		}
 		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;
 		}
@@ -154,8 +152,8 @@
 		}
 		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
 			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Hangup_Signaling_Link;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */

Modified: 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=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_ptp_monitor_flattened.fsm (original)
+++ team/group/ccss/doc/cc_ptp_monitor_flattened.fsm Wed Dec 23 13:13:53 2009
@@ -57,7 +57,6 @@
 		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
@@ -65,14 +64,16 @@
 			 * will be processed first.
 			 */
 			Action Post_HANGUP_SIGNALING;
+			Action Stop_T_ACTIVATE;
 			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;
+			Action Hangup_Signaling_Link;
+			Action Stop_T_ACTIVATE;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Claim it was a timeout */
@@ -83,8 +84,8 @@
 			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_CANCEL {
-			Action Stop_T_ACTIVATE;
-			Action Hangup_Signaling_Link;
+			Action Hangup_Signaling_Link;
+			Action Stop_T_ACTIVATE;
 			Action Set_Selfdestruct;
 			Next_State CC_STATE_IDLE;
 		}
@@ -133,9 +134,10 @@
 		}
 		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;
+			Action Hangup_Signaling_Link;
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -162,9 +164,10 @@
 		}
 		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;
+			Action Hangup_Signaling_Link;
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -192,9 +195,10 @@
 		}
 		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;
+			Action Hangup_Signaling_Link;
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */

Modified: team/group/ccss/doc/cc_qsig_agent.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_qsig_agent.fsm?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_qsig_agent.fsm (original)
+++ team/group/ccss/doc/cc_qsig_agent.fsm Wed Dec 23 13:13:53 2009
@@ -118,12 +118,12 @@
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
+				Action Hangup_Signaling_Link;
 			}
 			Test != TRUE {
 				Action Send_CC_Cancel(Q931_SETUP);
 			}
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -140,10 +140,11 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Next_State CC_STATE_IDLE;
 			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Next_State CC_STATE_IDLE;
 		}
 	}
 }

Modified: team/group/ccss/doc/cc_qsig_agent_flattened.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_qsig_agent_flattened.fsm?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_qsig_agent_flattened.fsm (original)
+++ team/group/ccss/doc/cc_qsig_agent_flattened.fsm Wed Dec 23 13:13:53 2009
@@ -91,13 +91,14 @@
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -115,13 +116,13 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Action Stop_T_SUPERVISION;
-				Action Set_Selfdestruct;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 	State CC_STATE_WAIT_CALLBACK {
@@ -141,13 +142,14 @@
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -165,13 +167,13 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Action Stop_T_SUPERVISION;
-				Action Set_Selfdestruct;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 	State CC_STATE_SUSPENDED {
@@ -186,13 +188,14 @@
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -210,13 +213,13 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Action Stop_T_SUPERVISION;
-				Action Set_Selfdestruct;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 }

Modified: team/group/ccss/doc/cc_qsig_monitor.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_qsig_monitor.fsm?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_qsig_monitor.fsm (original)
+++ team/group/ccss/doc/cc_qsig_monitor.fsm Wed Dec 23 13:13:53 2009
@@ -55,19 +55,20 @@
 			 *   Negotiated signaling link retention setting saved
 			 */
 			Action Stop_T_ACTIVATE;
-			Test = Get_Retain_Signaling_Link;
-			Test == TRUE {
-				Test = Get_msgtype;
-				Test == Q931_RELEASE {
+			Test = Get_msgtype;
+			Test == Q931_RELEASE {
+				Action Disassociate_Signaling_Link;
+				Test = Get_Retain_Signaling_Link;
+				Test == TRUE {
 					/*
 					 * The far end did not honor the
 					 * signaling link retention requirement.
+					 * ECMA-186 Section 6.5.2.2.1
 					 */
 					Action Pass_Up_CC_Req_Rsp_Timeout;
 					Action Pass_Up_CC_Cancel;
-					Action Disassociate_Signaling_Link;
 					Action Send_CC_Cancel(Q931_SETUP);
-					Next_State CC_STATE_WAIT_DESTRUCTION;
+					Next_State CC_STATE_IDLE;
 				}
 			}
 			Action Pass_Up_CC_Req_Rsp_Success;
@@ -90,8 +91,8 @@
 			Action Stop_T_ACTIVATE;
 			Action Pass_Up_CC_Req_Rsp_Timeout;
 			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Hangup_Signaling_Link;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			Action Stop_T_ACTIVATE;
@@ -124,8 +125,9 @@
 			}
 			Test != Q931_RELEASE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
+				Action Hangup_Signaling_Link;
+			}
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_CC_REQUEST_FAIL {
 			Action Stop_T_ACTIVATE;
@@ -205,8 +207,8 @@
 		Stimulus CC_EVENT_TIMEOUT_QSIG_CC_T3 {
 			Action Pass_Up_CC_Cancel;
 			Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-			Action Post_HANGUP_SIGNALING;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Hangup_Signaling_Link;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 	State CC_STATE_CALLBACK {
@@ -234,35 +236,36 @@
 		}
 		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
 			Action Pass_Up_CC_Cancel;
-			Test == Get_Signaling_Link_Active;
-			Test == TRUE {
-				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Next_State CC_STATE_WAIT_DESTRUCTION;
-		}
-		Stimulus CC_EVENT_SIGNALING_GONE {
-			/* Signaling link cleared. */
-			Action Disassociate_Signaling_Link;
-		}
-		Stimulus CC_EVENT_LINK_CANCEL {
-			/* Received ccCancel */
-			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
-		}
-		Stimulus CC_EVENT_CANCEL {
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Next_State CC_STATE_IDLE;
+		}
+		Stimulus CC_EVENT_SIGNALING_GONE {
+			/* Signaling link cleared. */
+			Action Disassociate_Signaling_Link;
+		}
+		Stimulus CC_EVENT_LINK_CANCEL {
+			/* Received ccCancel */
+			Action Pass_Up_CC_Cancel;
+			Action Post_HANGUP_SIGNALING;
 			Next_State CC_STATE_WAIT_DESTRUCTION;
 		}
+		Stimulus CC_EVENT_CANCEL {
+			Test == Get_Signaling_Link_Active;
+			Test == TRUE {
+				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Next_State CC_STATE_IDLE;
+		}
 	}
 }

Modified: team/group/ccss/doc/cc_qsig_monitor_flattened.fsm
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/doc/cc_qsig_monitor_flattened.fsm?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/doc/cc_qsig_monitor_flattened.fsm (original)
+++ team/group/ccss/doc/cc_qsig_monitor_flattened.fsm Wed Dec 23 13:13:53 2009
@@ -51,19 +51,21 @@
 			 *   Negotiated signaling link retention setting saved
 			 */
 			Action Stop_T_ACTIVATE;
-			Test = Get_Retain_Signaling_Link;
-			Test == TRUE {
-				Test = Get_msgtype;
-				Test == Q931_RELEASE {
+			Test = Get_msgtype;
+			Test == Q931_RELEASE {
+				Action Disassociate_Signaling_Link;
+				Test = Get_Retain_Signaling_Link;
+				Test == TRUE {
 					/*
 					 * The far end did not honor the
 					 * signaling link retention requirement.
+					 * ECMA-186 Section 6.5.2.2.1
 					 */
 					Action Pass_Up_CC_Req_Rsp_Timeout;
 					Action Pass_Up_CC_Cancel;
-					Action Disassociate_Signaling_Link;
 					Action Send_CC_Cancel(Q931_SETUP);
-					Next_State CC_STATE_WAIT_DESTRUCTION;
+					Action Set_Selfdestruct;
+					Next_State CC_STATE_IDLE;
 				}
 			}
 			Action Pass_Up_CC_Req_Rsp_Success;
@@ -89,8 +91,9 @@
 			Action Stop_T_ACTIVATE;
 			Action Pass_Up_CC_Req_Rsp_Timeout;
 			Action Pass_Up_CC_Cancel;
-			Action Post_HANGUP_SIGNALING;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Hangup_Signaling_Link;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			Action Stop_T_ACTIVATE;
@@ -124,8 +127,10 @@
 			}
 			Test != Q931_RELEASE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
+				Action Hangup_Signaling_Link;
+			}
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_CC_REQUEST_FAIL {
 			Action Stop_T_ACTIVATE;
@@ -197,13 +202,14 @@
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -221,13 +227,13 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Action Stop_T_SUPERVISION;
-				Action Set_Selfdestruct;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 	State CC_STATE_WAIT_CALLBACK {
@@ -249,25 +255,26 @@
 		Stimulus CC_EVENT_TIMEOUT_QSIG_CC_T3 {
 			Action Pass_Up_CC_Cancel;
 			Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-			Action Post_HANGUP_SIGNALING;
-			Action Stop_QSIG_CC_T3;
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			Action Hangup_Signaling_Link;
+			Action Stop_QSIG_CC_T3;
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
 			Action Pass_Up_CC_Cancel;
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Stop_QSIG_CC_T3;
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Action Stop_QSIG_CC_T3;
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_QSIG_CC_T3;
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -286,15 +293,14 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Action Stop_QSIG_CC_T3;
-				Action Stop_T_SUPERVISION;
-				Action Set_Selfdestruct;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Action Stop_QSIG_CC_T3;
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_QSIG_CC_T3;
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 	State CC_STATE_CALLBACK {
@@ -303,13 +309,14 @@
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -327,13 +334,13 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Action Stop_T_SUPERVISION;
-				Action Set_Selfdestruct;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 	State CC_STATE_SUSPENDED {
@@ -347,13 +354,14 @@
 			Test == Get_Signaling_Link_Active;
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
-				Action Post_HANGUP_SIGNALING;
-			}
-			Test != TRUE {
-				Action Send_CC_Cancel(Q931_SETUP);
-			}
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+				Action Hangup_Signaling_Link;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 		Stimulus CC_EVENT_SIGNALING_GONE {
 			/* Signaling link cleared. */
@@ -371,13 +379,13 @@
 			Test == TRUE {
 				Action Send_CC_Cancel(Q931_ANY_MESSAGE);
 				Action Hangup_Signaling_Link;
-				Action Stop_T_SUPERVISION;
-				Action Set_Selfdestruct;
-				Next_State CC_STATE_IDLE;
-			}
-			Action Send_CC_Cancel(Q931_SETUP);
-			Action Stop_T_SUPERVISION;
-			Next_State CC_STATE_WAIT_DESTRUCTION;
+			}
+			Test != TRUE {
+				Action Send_CC_Cancel(Q931_SETUP);
+			}
+			Action Stop_T_SUPERVISION;
+			Action Set_Selfdestruct;
+			Next_State CC_STATE_IDLE;
 		}
 	}
 }

Modified: team/group/ccss/pri_cc.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_cc.c?view=diff&rev=1398&r1=1397&r2=1398
==============================================================================
--- team/group/ccss/pri_cc.c (original)
+++ team/group/ccss/pri_cc.c Wed Dec 23 13:13:53 2009
@@ -343,6 +343,22 @@
 }
 
 /*!
+ * \internal
+ * \brief Disassociate the signaling link call from the cc_record.
+ *
+ * \param cc_record CC record to disassociate from the signaling link call.
+ *
+ * \return Nothing
+ */
+static void pri_cc_disassociate_signaling_link(struct pri_cc_record *cc_record)
+{
+	if (cc_record->signaling) {
+		cc_record->signaling->cc.record = NULL;
+		cc_record->signaling = NULL;
+	}
+}
+
+/*!
  * \brief Delete the given call completion record
  *
  * \param ctrl D channel controller.
@@ -360,10 +376,7 @@
 		doomed->original_call->cc.record = NULL;
 		doomed->original_call = NULL;
 	}
-	if (doomed->signaling) {
-		doomed->signaling->cc.record = NULL;
-		doomed->signaling = NULL;
-	}
+	pri_cc_disassociate_signaling_link(doomed);
 
 	ctrl = PRI_MASTER(ctrl);
 	for (prev = &ctrl->cc.pool, current = ctrl->cc.pool; current;
@@ -409,7 +422,6 @@
 	cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
 	cc_record->party_a = call->cc.party_a;
 	cc_record->party_b = call->called;
-	cc_record->party_b_is_remote = call->cc.party_b_is_remote;
 	cc_record->saved_ie_contents = call->cc.saved_ie_contents;
 	cc_record->bc = call->bc;
 	cc_record->option.recall_mode = ctrl->cc.option.recall_mode;
@@ -899,6 +911,127 @@
 
 /*!
  * \internal
+ * \brief Encode Q.SIG ccbsRequest/ccnrRequest 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_qsig_cc_request(struct pri *ctrl,
+	unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record)
+{
+	struct fac_extension_header header;
+	struct rose_msg_invoke msg;
+
+	memset(&header, 0, sizeof(header));
+	header.nfe_present = 1;
+	header.nfe.source_entity = 0;	/* endPINX */
+	header.nfe.destination_entity = 0;	/* endPINX */
+	header.interpretation_present = 1;
+	header.interpretation = 1;	/* clearCallIfAnyInvokePduNotRecognised */
+	pos = facility_encode_header(ctrl, pos, end, &header);
+	if (!pos) {
+		return NULL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.invoke_id = get_invokeid(ctrl);
+	msg.operation = cc_record->is_ccnr
+		? ROSE_QSIG_CcnrRequest : ROSE_QSIG_CcbsRequest;
+
+	/* Fill in Party B address. */
+	q931_copy_number_to_rose(ctrl, &msg.args.qsig.CcbsRequest.number_b,
+		&cc_record->party_b.number);
+	q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcbsRequest.subaddr_b,
+		&cc_record->party_b.subaddress);
+
+	/* Fill in Party A address. */
+	q931_copy_presented_number_unscreened_to_rose(ctrl,
+		&msg.args.qsig.CcbsRequest.number_a, &cc_record->party_a.number);
+	q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcbsRequest.subaddr_a,
+		&cc_record->party_a.subaddress);
+
+	/* Fill in service Q.931 ie information. */
+	if (cc_record->saved_ie_contents.length
+		<= sizeof(msg.args.qsig.CcbsRequest.q931ie_contents)) {
+		/* Saved BC, HLC, and LLC from initial SETUP */
+		msg.args.qsig.CcbsRequest.q931ie.length = cc_record->saved_ie_contents.length;
+		memcpy(msg.args.qsig.CcbsRequest.q931ie.contents,
+			cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
+	} else {
+		pri_error(ctrl, "CcbsRequest q931 ie contents did not fit.\n");
+	}
+
+	//msg.args.qsig.CcbsRequest.can_retain_service = 0;
+
+	switch (PRI_MASTER(ctrl)->cc.option.signaling_retention_req) {
+	case 0:/* Want release signaling link. */
+		msg.args.qsig.CcbsRequest.retain_sig_connection_present = 1;
+		msg.args.qsig.CcbsRequest.retain_sig_connection = 0;
+		break;
+	case 1:/* Demand retain signaling link. */
+		msg.args.qsig.CcbsRequest.retain_sig_connection_present = 1;
+		msg.args.qsig.CcbsRequest.retain_sig_connection = 1;
+		break;
+	case 2:/* Don't care about signaling link retention. */
+	default:
+		break;
+	}
+
+	pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+	return pos;
+}
+
+/*!
+ * \internal
+ * \brief Encode Q.SIG ccSuspend/ccResume/ccPathReserve/ccRingout 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 operation Q.SIG call completion event operation to encode.
+ * \param interpretation Component interpretation:
+ * discardAnyUnrecognisedInvokePdu(0),
+ * clearCallIfAnyInvokePduNotRecognised(1),
+ * rejectAnyUnrecognisedInvokePdu(2)
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_qsig_cc_extension_event(struct pri *ctrl,
+	unsigned char *pos, unsigned char *end, enum rose_operation operation,
+	int interpretation)
+{
+	struct fac_extension_header header;
+	struct rose_msg_invoke msg;
+
+	memset(&header, 0, sizeof(header));
+	header.nfe_present = 1;
+	header.nfe.source_entity = 0;	/* endPINX */
+	header.nfe.destination_entity = 0;	/* endPINX */
+	header.interpretation_present = 1;
+	header.interpretation = interpretation;
+	pos = facility_encode_header(ctrl, pos, end, &header);
+	if (!pos) {
+		return NULL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.invoke_id = get_invokeid(ctrl);
+	msg.operation = operation;
+
+	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.
@@ -1117,6 +1250,74 @@
 		&cc_record->party_b);
 	msg.args.etsi.CCBSRemoteUserFree.recall_mode = cc_record->option.recall_mode;
 	msg.args.etsi.CCBSRemoteUserFree.ccbs_reference = cc_record->ccbs_reference_id;
+
+	pos = rose_encode_invoke(ctrl, pos, end, &msg);
+
+	return pos;
+}
+
+/*!
+ * \internal
+ * \brief Encode Q.SIG CcOptionalArg for ccCancel/ccExecPossible 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.
+ * \param msgtype Q.931 message type to put facility ie in.
+ * \param operation library encoded operation-value
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_qsig_cc_optional_arg(struct pri *ctrl,
+	unsigned char *pos, unsigned char *end, struct pri_cc_record *cc_record, int msgtype,
+	enum rose_operation operation)
+{
+	struct fac_extension_header header;
+	struct rose_msg_invoke msg;
+
+	memset(&header, 0, sizeof(header));
+	header.nfe_present = 1;
+	header.nfe.source_entity = 0;	/* endPINX */
+	header.nfe.destination_entity = 0;	/* endPINX */
+	header.interpretation_present = 1;
+	header.interpretation = 1;	/* clearCallIfAnyInvokePduNotRecognised */
+	pos = facility_encode_header(ctrl, pos, end, &header);
+	if (!pos) {
+		return NULL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.invoke_id = get_invokeid(ctrl);
+	msg.operation = operation;
+
+	if (cc_record && msgtype == Q931_SETUP) {
+		msg.args.qsig.CcCancel.full_arg_present = 1;
+
+		/* Fill in Party A address. */
+		q931_copy_number_to_rose(ctrl, &msg.args.qsig.CcCancel.number_a,
+			&cc_record->party_a.number);
+		q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcCancel.subaddr_a,
+			&cc_record->party_a.subaddress);
+
+		/* Fill in Party B address. */
+		q931_copy_number_to_rose(ctrl, &msg.args.qsig.CcCancel.number_b,
+			&cc_record->party_b.number);
+		q931_copy_subaddress_to_rose(ctrl, &msg.args.qsig.CcCancel.subaddr_b,
+			&cc_record->party_b.subaddress);
+
+		/* Fill in service Q.931 ie information. */
+		if (cc_record->saved_ie_contents.length
+			<= sizeof(msg.args.qsig.CcCancel.q931ie_contents)) {
+			/* Saved BC, HLC, and LLC from initial SETUP */
+			msg.args.qsig.CcCancel.q931ie.length = cc_record->saved_ie_contents.length;
+			memcpy(msg.args.qsig.CcCancel.q931ie.contents,
+				cc_record->saved_ie_contents.data, cc_record->saved_ie_contents.length);
+		} else {
+			pri_error(ctrl, "CcOptionalArg q931 ie contents did not fit.\n");
+		}
+	}
 
 	pos = rose_encode_invoke(ctrl, pos, end, &msg);
 
@@ -1154,8 +1355,9 @@
 		}
 		break;
 	case PRI_SWITCH_QSIG:
-		/*! \todo BUGBUG rose_remote_user_free_encode(Q.SIG) not written. */
-		return -1;
+		end = enc_qsig_cc_optional_arg(ctrl, buffer, buffer + sizeof(buffer), cc_record,
+			msgtype, ROSE_QSIG_CcExecPossible);
+		break;
 	default:
 		return -1;
 	}
@@ -1168,30 +1370,135 @@
 
 /*!
  * \internal
- * \brief Encode and send an remote user free message.
+ * \brief Encode and send a CC facility event in a SETUP message.
  *
  * \param ctrl D channel controller for diagnostic messages or global options.
- * \param call Call leg from which to encode remote user free.
- * \param cc_record Call completion record to process event.
+ * \param cc_record Call completion record to process event.
+ * \param encode Function to encode facility to send out in SETUP message.
  *
  * \retval 0 on success.
  * \retval -1 on error.
  */
-static int send_remote_user_free(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record)
-{
+static int pri_cc_send_setup_encode(struct pri *ctrl, struct pri_cc_record *cc_record,
+	int (*encode)(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record,
+		int msgtype))
+{
+	struct pri_sr req;
+	q931_call *call;
+
+	call = q931_new_call(ctrl);
+	if (!call) {
+		return -1;
+	}
+
+	/* Link the new call as the signaling link. */
+	cc_record->signaling = call;
+	call->cc.record = cc_record;
+
+	if (encode(ctrl, call, cc_record, Q931_SETUP)) {
+		/* Should not happen. */
+		q931_destroycall(ctrl, call);
+		return -1;
+	}
+
+	pri_sr_init(&req);
+	if (cc_record->is_agent) {
+		q931_party_address_to_id(&req.caller, &cc_record->party_b);
+		q931_party_id_to_address(&req.called, &cc_record->party_a);
+	} else {
+		req.caller = cc_record->party_a;
+		req.called = cc_record->party_b;
+	}
+	//req.cis_auto_disconnect = 0;
+	req.cis_call = 1;
+	if (q931_setup(ctrl, call, &req)) {
+		/* Should not happen. */
+		q931_destroycall(ctrl, call);
+		return -1;
+	}
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Encode and send an remote user free 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_remote_user_free(struct pri *ctrl, struct pri_cc_record *cc_record)
+{
+	int retval;
+	q931_call *call;
+
 /*
  * XXX May need to add called-party-ie with Party A number in FACILITY message. (CCBSRemoteUserFree)
  * ETSI EN 300-195-1 Section 5.41 MSN interaction.
  */
-	if (rose_remote_user_free_encode(ctrl, call, cc_record, Q931_FACILITY)
-		|| q931_facility(ctrl, call)) {
-		pri_message(ctrl,
-			"Could not schedule facility message for remote user free.\n");
+	retval = -1;
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_EUROISDN_E1:
+	case PRI_SWITCH_EUROISDN_T1:
+		call = cc_record->signaling;
+		retval = rose_remote_user_free_encode(ctrl, call, cc_record, Q931_FACILITY);
+		if (!retval) {
+			retval = q931_facility(ctrl, call);
+		}
+		break;
+	case PRI_SWITCH_QSIG:
+		/* ccExecPossible could be sent in FACILITY or SETUP. */
+		call = cc_record->signaling;
+		if (call) {
+			retval = rose_remote_user_free_encode(ctrl, call, cc_record, Q931_FACILITY);
+			if (!retval) {
+				retval = q931_facility(ctrl, call);
+			}
+		} else {
+			retval = pri_cc_send_setup_encode(ctrl, cc_record,
+				rose_remote_user_free_encode);
+		}
+		break;
+	default:
+		break;
+	}
+	if (retval) {
+		pri_message(ctrl, "Could not schedule message for remote user free.\n");
 		return -1;
 	}
-
 	return 0;
 }
+
+/*!
+ * \internal
+ * \brief Encode and queue a Q.SIG ccCancel message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param call Call leg from which to encode remote user free message.
+ * \param cc_record Call completion record to process event.
+ * \param msgtype Q.931 message type to put facility ie in.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int rose_cc_cancel(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record, int msgtype)
+{
+	unsigned char buffer[256];
+	unsigned char *end;
+
+	end = enc_qsig_cc_optional_arg(ctrl, buffer, buffer + sizeof(buffer), cc_record,
+		msgtype, ROSE_QSIG_CcCancel);
+	if (!end) {
+		return -1;
+	}
+
+	return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL);
+}
+
+/* BUGBUG ccCancel could be sent in SETUP or RELEASE. */
+/* If ccPathReserve is supported it could also be sent in DISCONNECT. */
 
 /*!
  * \internal
@@ -1217,8 +1524,10 @@
 				ROSE_ETSI_CCBS_T_Suspend);
 		break;
 	case PRI_SWITCH_QSIG:
-		/*! \todo BUGBUG rose_cc_suspend_encode(Q.SIG) not written. */
-		return -1;
+		end =
+			enc_qsig_cc_extension_event(ctrl, buffer, buffer + sizeof(buffer),
+				ROSE_QSIG_CcSuspend, 0/* discardAnyUnrecognisedInvokePdu */);
+		break;
 	default:
 		return -1;
 	}
@@ -1241,27 +1550,46 @@
  */
 static int send_cc_suspend(struct pri *ctrl, struct pri_cc_record *cc_record)
 {
+	int retval;
 	q931_call *call;
 
+	retval = -1;
 	switch (ctrl->switchtype) {
 	case PRI_SWITCH_EUROISDN_E1:
 	case PRI_SWITCH_EUROISDN_T1:
 		call = cc_record->signaling;
+		retval = rose_cc_suspend_encode(ctrl, call, Q931_FACILITY);
+		if (!retval) {
+			retval = q931_facility(ctrl, call);
+		}
+		break;
+	case PRI_SWITCH_QSIG:
+		/*
+		 * Suspend is sent in a CONNECT or FACILITY message.
+		 * If ccPathReserve is supported, it could also be sent in
+		 * RELEASE or DISCONNECT.
+		 */
+		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 */
+			break;
+		}
+		retval = rose_cc_suspend_encode(ctrl, call, Q931_ANY_MESSAGE);
+		if (!retval) {
+			if (call->ourcallstate == Q931_CALL_STATE_ACTIVE) {
+				retval = q931_facility(ctrl, call);
+			} else {
+				retval = q931_connect(ctrl, call, 0, 0);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+	if (retval) {
+		pri_message(ctrl, "Could not schedule message for CC suspend.\n");
 		return -1;
-	default:
-		return -1;
-	}
+	}
+	return 0;
 }
 
 /*!
@@ -1288,8 +1616,10 @@
 				ROSE_ETSI_CCBS_T_Resume);
 		break;
 	case PRI_SWITCH_QSIG:

[... 1138 lines stripped ...]



More information about the libpri-commits mailing list