1/*
2 * FSM pseudo code used in the design/implementation of the CC PTMP agent.
3 */
4FSM CC_PTMP_Agent
5{
6	State CC_STATE_IDLE {
7		Init {
8		}
9		Prolog {
10			Action Set_Selfdestruct;
11		}
12		Stimulus CC_EVENT_AVAILABLE {
13			Next_State CC_STATE_PENDING_AVAILABLE;
14		}
15		Stimulus CC_EVENT_CANCEL {
16			Action Set_Selfdestruct;
17		}
18	}
19	State CC_STATE_PENDING_AVAILABLE {
20		Stimulus CC_EVENT_MSG_ALERTING {
21			Action Send_CC_Available(Q931_ALERTING);
22			Next_State CC_STATE_AVAILABLE;
23		}
24		Stimulus CC_EVENT_MSG_DISCONNECT {
25			Action Send_CC_Available(Q931_DISCONNECT);
26			Next_State CC_STATE_AVAILABLE;
27		}
28		Stimulus CC_EVENT_INTERNAL_CLEARING {
29			Action Release_LinkID;
30			Action Pass_Up_CC_Cancel;
31			Next_State CC_STATE_IDLE;
32		}
33		Stimulus CC_EVENT_CANCEL {
34			Action Release_LinkID;
35			Next_State CC_STATE_IDLE;
36		}
37	}
38	State CC_STATE_AVAILABLE {
39		Epilog {
40			Action Stop_T_RETENTION;
41		}
42		Stimulus CC_EVENT_MSG_RELEASE {
43			Action Stop_T_RETENTION;
44			Action Start_T_RETENTION;
45		}
46		Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
47			Action Stop_T_RETENTION;
48			Action Start_T_RETENTION;
49		}
50		Stimulus CC_EVENT_CC_REQUEST {
51			Action Pass_Up_CC_Request;
52			Next_State CC_STATE_REQUESTED;
53		}
54		Stimulus CC_EVENT_INTERNAL_CLEARING {
55			Action Stop_T_RETENTION;
56			Action Start_T_RETENTION;
57		}
58		Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
59			Action Send_EraseCallLinkageID;
60			Action Release_LinkID;
61			Action Pass_Up_CC_Cancel;
62			Next_State CC_STATE_IDLE;
63		}
64		Stimulus CC_EVENT_CANCEL {
65			Action Send_EraseCallLinkageID;
66			Action Release_LinkID;
67			Next_State CC_STATE_IDLE;
68		}
69	}
70	State CC_STATE_REQUESTED {
71		Epilog {
72			Action Send_EraseCallLinkageID;
73			Action Release_LinkID;
74		}
75		Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
76			Next_State CC_STATE_ACTIVATED;
77		}
78		Stimulus CC_EVENT_CANCEL {
79			Next_State CC_STATE_IDLE;
80		}
81	}
82/*
83 * Pass_Up_A_Status passes up the current final status of A.
84 * Does nothing if status is invalid.
85 *
86 * Pass_Up_A_Status_Indirect is the same as Pass_Up_A_Status but
87 * sets a timer to expire immediately to pass up the event.
88 * Does nothing if status is invalid.
89 *
90 * Pass_Up_Status_Rsp_A passes up the current accumulated status of A.
91 * Does nothing if status is invalid.
92 *
93 * Pass_Up_Status_Rsp_A_Indirect is the same as Pass_Up_Status_Rsp_A but
94 * sets a timer to expire immediately to pass up the event.
95 * Does nothing if status is invalid.
96 */
97	State CC_STATE_ACTIVATED {
98		Prolog {
99			Action Reset_A_Status;
100			Action Raw_Status_Count_Reset;
101		}
102		Stimulus CC_EVENT_RECALL {
103			Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
104			Action Set_Call_To_Hangup;
105		}
106		Stimulus CC_EVENT_B_FREE {
107			Action Send_CCBSBFree;
108		}
109		Stimulus CC_EVENT_REMOTE_USER_FREE {
110			Test = Get_A_Status;
111			Test == Invalid {
112				Next_State CC_STATE_B_AVAILABLE;
113			}
114			Test == Busy {
115				Action Pass_Up_A_Status_Indirect;
116				Action Send_CCBSBFree;
117				Next_State CC_STATE_SUSPENDED;
118			}
119			Test == Free {
120				//Action Pass_Up_A_Status_Indirect;
121				Action Send_RemoteUserFree;
122				Next_State CC_STATE_WAIT_CALLBACK;
123			}
124		}
125		Stimulus CC_EVENT_A_STATUS {
126			Test = Get_T_CCBS1_Status;
127			Test == Active {
128				Action Pass_Up_Status_Rsp_A_Indirect;
129				Next_State $;
130			}
131			Test != Active {
132				Action Reset_A_Status;
133				Action Reset_Raw_A_Status;
134				Action Send_CCBSStatusRequest;
135				Action Start_T_CCBS1;
136				Action Stop_Extended_T_CCBS1;
137				Action Start_Extended_T_CCBS1;
138				Next_State $;
139			}
140		}
141		Stimulus CC_EVENT_A_FREE {
142			Action Raw_Status_Count_Reset;
143			Action Set_Raw_A_Status_Free;
144			Action Promote_Raw_A_Status;
145			Action Pass_Up_Status_Rsp_A;
146			Action Stop_T_CCBS1;
147		}
148		Stimulus CC_EVENT_A_BUSY {
149			Action Add_Raw_A_Status_Busy;
150			Action Pass_Up_Status_Rsp_A;
151		}
152		Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
153			Action Promote_Raw_A_Status;
154			Test = Get_A_Status;
155			Test != Invalid {
156				/* Only received User A busy. */
157				Action Raw_Status_Count_Reset;
158			}
159			Test == Invalid {
160				/* Did not get any responses. */
161				Action Raw_Status_Count_Increment;
162				Test = Get_Raw_Status_Count;
163				Test >= RAW_STATUS_COUNT_MAX {
164					/* User A no longer present. */
165					Action Send_CCBSErase(Normal_Unspecified);
166					Action Pass_Up_CC_Cancel;
167					Next_State CC_STATE_IDLE;
168				}
169			}
170		}
171		Stimulus CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1 {
172			Action Reset_A_Status;
173			Action Raw_Status_Count_Reset;
174		}
175	}
176	State CC_STATE_B_AVAILABLE {
177		/* A status is always invalid on entry. */
178		Prolog {
179			Test = Get_T_CCBS1_Status;
180			Test != Active {
181				Action Reset_Raw_A_Status;
182				Action Send_CCBSStatusRequest;
183				Action Start_T_CCBS1;
184			}
185		}
186		Stimulus CC_EVENT_RECALL {
187			Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
188			Action Set_Call_To_Hangup;
189		}
190		Stimulus CC_EVENT_A_STATUS {
191			Action Stop_Extended_T_CCBS1;
192			Action Start_Extended_T_CCBS1;
193			Action Pass_Up_Status_Rsp_A_Indirect;
194		}
195		Stimulus CC_EVENT_A_FREE {
196			Action Send_RemoteUserFree;
197			Action Set_Raw_A_Status_Free;
198			//Action Promote_Raw_A_Status;
199			//Action Pass_Up_A_Status;
200			Test = Get_Extended_T_CCBS1_Status;
201			Test == Active {
202				Action Pass_Up_Status_Rsp_A;
203			}
204			Next_State CC_STATE_WAIT_CALLBACK;
205		}
206		Stimulus CC_EVENT_A_BUSY {
207			Action Add_Raw_A_Status_Busy;
208			Test = Get_Extended_T_CCBS1_Status;
209			Test == Active {
210				Action Pass_Up_Status_Rsp_A;
211			}
212		}
213		Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
214			Test = Get_Raw_A_Status;
215			Test != Invalid {
216				/* Only received User A is busy. */
217				Action Raw_Status_Count_Reset;
218				Action Send_CCBSBFree;
219				Action Promote_Raw_A_Status;
220				Action Pass_Up_A_Status;
221				Next_State CC_STATE_SUSPENDED;
222			}
223			Test == Invalid {
224				/* Did not get any responses. */
225				Action Raw_Status_Count_Increment;
226				Test = Get_Raw_Status_Count;
227				Test >= RAW_STATUS_COUNT_MAX {
228					/* User A no longer present. */
229					Action Send_CCBSErase(Normal_Unspecified);
230					Action Pass_Up_CC_Cancel;
231					Next_State CC_STATE_IDLE;
232				}
233				//Action Reset_Raw_A_Status;
234				Action Send_CCBSStatusRequest;
235				Action Start_T_CCBS1;
236			}
237		}
238	}
239	State CC_STATE_SUSPENDED {
240		Prolog {
241			Test = Get_T_CCBS1_Status;
242			Test != Active {
243				Action Reset_Raw_A_Status;
244				Action Send_CCBSStatusRequest;
245				Action Start_T_CCBS1;
246			}
247		}
248		Stimulus CC_EVENT_RECALL {
249			Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
250			Action Set_Call_To_Hangup;
251		}
252		Stimulus CC_EVENT_A_STATUS {
253			Action Stop_Extended_T_CCBS1;
254			Action Start_Extended_T_CCBS1;
255			Action Pass_Up_Status_Rsp_A_Indirect;
256		}
257		Stimulus CC_EVENT_A_FREE {
258			Action Set_Raw_A_Status_Free;
259			Action Promote_Raw_A_Status;
260			Action Pass_Up_A_Status;
261			Test = Get_Extended_T_CCBS1_Status;
262			Test == Active {
263				Action Pass_Up_Status_Rsp_A;
264			}
265			Action Stop_T_CCBS1;
266			Action Stop_Extended_T_CCBS1;
267			Next_State CC_STATE_ACTIVATED;
268		}
269		Stimulus CC_EVENT_A_BUSY {
270			Action Add_Raw_A_Status_Busy;
271			Test = Get_Extended_T_CCBS1_Status;
272			Test == Active {
273				Action Pass_Up_Status_Rsp_A;
274			}
275		}
276		Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
277			Test = Get_Raw_A_Status;
278			Test != Invalid {
279				/* Only received User A is busy. */
280				Action Raw_Status_Count_Reset;
281			}
282			Test == Invalid {
283				/* Did not get any responses. */
284				Action Raw_Status_Count_Increment;
285				Test = Get_Raw_Status_Count;
286				Test >= RAW_STATUS_COUNT_MAX {
287					/* User A no longer present. */
288					Action Send_CCBSErase(Normal_Unspecified);
289					Action Pass_Up_CC_Cancel;
290					Next_State CC_STATE_IDLE;
291				}
292			}
293			Action Reset_Raw_A_Status;
294			Action Send_CCBSStatusRequest;
295			Action Start_T_CCBS1;
296		}
297	}
298	State CC_STATE_WAIT_CALLBACK {
299		Prolog {
300			/* Start T_CCBS3 */
301			Action Start_T_RECALL;
302		}
303		Epilog {
304			Action Stop_T_RECALL;
305		}
306		Stimulus CC_EVENT_TIMEOUT_T_RECALL {
307			Action Pass_Up_CC_Cancel;
308			Action Send_CCBSErase(T_CCBS3_TIMEOUT);
309			Next_State CC_STATE_IDLE;
310		}
311		Stimulus CC_EVENT_STOP_ALERTING {
312			/*
313			 * If an earlier link can send us this event then we
314			 * really should be configured for globalRecall like
315			 * the earlier link.
316			 */
317			Test = Get_Recall_Mode;
318			Test == globalRecall {
319				Action Send_CCBSStopAlerting;
320			}
321			Next_State CC_STATE_ACTIVATED;
322		}
323		Stimulus CC_EVENT_RECALL {
324			Action Pass_Up_CC_Call;
325			Action Set_Original_Call_Parameters;
326			Test = Get_Recall_Mode;
327			Test == globalRecall {
328				Action Send_CCBSStopAlerting;
329			}
330			Next_State CC_STATE_CALLBACK;
331		}
332		Stimulus CC_EVENT_A_STATUS {
333			Action Set_Raw_A_Status_Free;
334			Action Pass_Up_Status_Rsp_A_Indirect;
335		}
336	}
337	State CC_STATE_CALLBACK {
338		Stimulus CC_EVENT_RECALL {
339			Action Send_Error_Recall(ROSE_ERROR_CCBS_AlreadyAccepted);
340			Action Set_Call_To_Hangup;
341		}
342		Stimulus CC_EVENT_A_STATUS {
343			Action Set_Raw_A_Status_Free;
344			Action Pass_Up_Status_Rsp_A_Indirect;
345		}
346	}
347	Superstate CC_ACTIVE(CC_STATE_ACTIVATED, CC_STATE_B_AVAILABLE, CC_STATE_SUSPENDED, CC_STATE_WAIT_CALLBACK, CC_STATE_CALLBACK) {
348		Prolog {
349			/* Start T_CCBS2 or T_CCNR2 depending upon CC mode. */
350			Action Start_T_SUPERVISION;
351		}
352		Epilog {
353			Action Stop_T_SUPERVISION;
354		}
355		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
356			Action Pass_Up_CC_Cancel;
357			Action Send_CCBSErase(T_CCBS2_TIMEOUT);
358			Next_State CC_STATE_IDLE;
359		}
360		Stimulus CC_EVENT_LINK_CANCEL {
361			Action Pass_Up_CC_Cancel;
362			Action Send_CCBSErase(Normal_Unspecified);
363			Next_State CC_STATE_IDLE;
364		}
365		Stimulus CC_EVENT_CANCEL {
366			Action Send_CCBSErase(Normal_Unspecified);
367			Next_State CC_STATE_IDLE;
368		}
369	}
370	Superstate CC_STATUS(CC_STATE_ACTIVATED, CC_STATE_B_AVAILABLE, CC_STATE_SUSPENDED) {
371		Epilog {
372			Action Stop_T_CCBS1;
373			Action Stop_Extended_T_CCBS1;
374		}
375	}
376}
377