/*
 * FSM pseudo code used in the design/implementation of the CC Q.SIG agent.
 */
FSM CC_QSIG_Agent
{
	State CC_STATE_IDLE {
		Init {
		}
		Prolog {
			Action Set_Selfdestruct;
		}
		Stimulus CC_EVENT_AVAILABLE {
			Next_State CC_STATE_AVAILABLE;
		}
		Stimulus CC_EVENT_CANCEL {
			Action Set_Selfdestruct;
		}
	}
	State CC_STATE_AVAILABLE {
		/*
		 * For Q.SIG mode the T_RETENTION timer is not defined.  However,
		 * we will use it anyway in this state to protect our resources
		 * from leaks caused by user A not requesting CC.  This timer
		 * should be set much longer than the PTMP network link to
		 * allow for variations in user A's CC offer timer.
		 */
		Epilog {
			Action Stop_T_RETENTION;
		}
		Stimulus CC_EVENT_MSG_RELEASE {
			Action Stop_T_RETENTION;
			Action Start_T_RETENTION;
		}
		Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
			Action Stop_T_RETENTION;
			Action Start_T_RETENTION;
		}
		Stimulus CC_EVENT_CC_REQUEST {
			Action Pass_Up_CC_Request;
			/* Send Q931_CALL_PROCEEDING message on signaling link. */
			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;
		}
		Stimulus CC_EVENT_CANCEL {
			Next_State CC_STATE_IDLE;
		}
	}
	State CC_STATE_REQUESTED {
		Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
			Next_State CC_STATE_ACTIVATED;
		}
		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;
		}
	}
	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;
		}
	}
	State CC_STATE_ACTIVATED {
		Stimulus CC_EVENT_REMOTE_USER_FREE {
			/* Send ccExecPossible in FACILITY or SETUP. */
			Action Send_RemoteUserFree;
			Next_State CC_STATE_WAIT_CALLBACK;
		}
	}
	State CC_STATE_WAIT_CALLBACK {
		Stimulus CC_EVENT_SUSPEND {
			/* Received ccSuspend */
			Action Set_A_Status_Busy;
			Action Pass_Up_A_Status;
			Next_State CC_STATE_SUSPENDED;
		}
		Stimulus CC_EVENT_RECALL {
			/* Received ccRingout */
			Action Pass_Up_CC_Call;
			Action Set_Original_Call_Parameters;
		}
	}
	State CC_STATE_SUSPENDED {
		Stimulus CC_EVENT_RESUME {
			/* Received ccResume */
			Action Set_A_Status_Free;
			Action Pass_Up_A_Status;
			Next_State CC_STATE_ACTIVATED;
		}
	}
	Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_WAIT_CALLBACK, CC_STATE_SUSPENDED) {
		Prolog {
			/* Start QSIG_CCBS_T2/QSIG_CCNR_T2 depending upon CC mode. */
			Action Start_T_SUPERVISION;
		}
		Epilog {
			Action Stop_T_SUPERVISION;
		}
		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
			Action Pass_Up_CC_Cancel;
			Action Send_CC_Cancel;
			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 {
			Action Send_CC_Cancel;
			Next_State CC_STATE_IDLE;
		}
	}
}
