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		Stimulus CC_EVENT_AVAILABLE {
8			Next_State CC_STATE_PENDING_AVAILABLE;
9		}
10		Stimulus CC_EVENT_CANCEL {
11			Action Set_Selfdestruct;
12		}
13	}
14	State CC_STATE_PENDING_AVAILABLE {
15		Stimulus CC_EVENT_MSG_ALERTING {
16			Action Send_CC_Available(Q931_ALERTING);
17			Next_State CC_STATE_AVAILABLE;
18		}
19		Stimulus CC_EVENT_MSG_DISCONNECT {
20			Action Send_CC_Available(Q931_DISCONNECT);
21			Next_State CC_STATE_AVAILABLE;
22		}
23		Stimulus CC_EVENT_INTERNAL_CLEARING {
24			Action Release_LinkID;
25			Action Pass_Up_CC_Cancel;
26			Action Set_Selfdestruct;
27			Next_State CC_STATE_IDLE;
28		}
29		Stimulus CC_EVENT_CANCEL {
30			Action Release_LinkID;
31			Action Set_Selfdestruct;
32			Next_State CC_STATE_IDLE;
33		}
34	}
35	State CC_STATE_AVAILABLE {
36		Stimulus CC_EVENT_MSG_RELEASE {
37			Action Stop_T_RETENTION;
38			Action Start_T_RETENTION;
39		}
40		Stimulus CC_EVENT_MSG_RELEASE_COMPLETE {
41			Action Stop_T_RETENTION;
42			Action Start_T_RETENTION;
43		}
44		Stimulus CC_EVENT_CC_REQUEST {
45			Action Pass_Up_CC_Request;
46			Action Stop_T_RETENTION;
47			Next_State CC_STATE_REQUESTED;
48		}
49		Stimulus CC_EVENT_INTERNAL_CLEARING {
50			Action Stop_T_RETENTION;
51			Action Start_T_RETENTION;
52		}
53		Stimulus CC_EVENT_TIMEOUT_T_RETENTION {
54			Action Send_EraseCallLinkageID;
55			Action Release_LinkID;
56			Action Pass_Up_CC_Cancel;
57			Action Stop_T_RETENTION;
58			Action Set_Selfdestruct;
59			Next_State CC_STATE_IDLE;
60		}
61		Stimulus CC_EVENT_CANCEL {
62			Action Send_EraseCallLinkageID;
63			Action Release_LinkID;
64			Action Stop_T_RETENTION;
65			Action Set_Selfdestruct;
66			Next_State CC_STATE_IDLE;
67		}
68	}
69	State CC_STATE_REQUESTED {
70		Stimulus CC_EVENT_CC_REQUEST_ACCEPT {
71			Action Send_EraseCallLinkageID;
72			Action Release_LinkID;
73			/* Start T_CCBS2 or T_CCNR2 depending upon CC mode. */
74			Action Start_T_SUPERVISION;
75			Action Reset_A_Status;
76			Action Raw_Status_Count_Reset;
77			Next_State CC_STATE_ACTIVATED;
78		}
79		Stimulus CC_EVENT_CANCEL {
80			Action Send_EraseCallLinkageID;
81			Action Release_LinkID;
82			Action Set_Selfdestruct;
83			Next_State CC_STATE_IDLE;
84		}
85	}
86/*
87 * Pass_Up_A_Status passes up the current final status of A.
88 * Does nothing if status is invalid.
89 *
90 * Pass_Up_A_Status_Indirect is the same as Pass_Up_A_Status but
91 * sets a timer to expire immediately to pass up the event.
92 * Does nothing if status is invalid.
93 *
94 * Pass_Up_Status_Rsp_A passes up the current accumulated status of A.
95 * Does nothing if status is invalid.
96 *
97 * Pass_Up_Status_Rsp_A_Indirect is the same as Pass_Up_Status_Rsp_A but
98 * sets a timer to expire immediately to pass up the event.
99 * Does nothing if status is invalid.
100 */
101	State CC_STATE_ACTIVATED {
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				Test = Get_T_CCBS1_Status;
113				Test != Active {
114					Action Reset_Raw_A_Status;
115					Action Send_CCBSStatusRequest;
116					Action Start_T_CCBS1;
117				}
118				Next_State CC_STATE_B_AVAILABLE;
119			}
120			Test == Busy {
121				Action Pass_Up_A_Status_Indirect;
122				Action Send_CCBSBFree;
123				Test = Get_T_CCBS1_Status;
124				Test != Active {
125					Action Reset_Raw_A_Status;
126					Action Send_CCBSStatusRequest;
127					Action Start_T_CCBS1;
128				}
129				Next_State CC_STATE_SUSPENDED;
130			}
131			Test == Free {
132				//Action Pass_Up_A_Status_Indirect;
133				Action Send_RemoteUserFree;
134				Action Stop_T_CCBS1;
135				Action Stop_Extended_T_CCBS1;
136				/* Start T_CCBS3 */
137				Action Start_T_RECALL;
138				Next_State CC_STATE_WAIT_CALLBACK;
139			}
140		}
141		Stimulus CC_EVENT_A_STATUS {
142			Test = Get_T_CCBS1_Status;
143			Test == Active {
144				Action Pass_Up_Status_Rsp_A_Indirect;
145				Next_State $;
146			}
147			Test != Active {
148				Action Reset_A_Status;
149				Action Reset_Raw_A_Status;
150				Action Send_CCBSStatusRequest;
151				Action Start_T_CCBS1;
152				Action Stop_Extended_T_CCBS1;
153				Action Start_Extended_T_CCBS1;
154				Next_State $;
155			}
156		}
157		Stimulus CC_EVENT_A_FREE {
158			Action Raw_Status_Count_Reset;
159			Action Set_Raw_A_Status_Free;
160			Action Promote_Raw_A_Status;
161			Action Pass_Up_Status_Rsp_A;
162			Action Stop_T_CCBS1;
163		}
164		Stimulus CC_EVENT_A_BUSY {
165			Action Add_Raw_A_Status_Busy;
166			Action Pass_Up_Status_Rsp_A;
167		}
168		Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
169			Action Promote_Raw_A_Status;
170			Test = Get_A_Status;
171			Test != Invalid {
172				/* Only received User A busy. */
173				Action Raw_Status_Count_Reset;
174			}
175			Test == Invalid {
176				/* Did not get any responses. */
177				Action Raw_Status_Count_Increment;
178				Test = Get_Raw_Status_Count;
179				Test >= RAW_STATUS_COUNT_MAX {
180					/* User A no longer present. */
181					Action Send_CCBSErase(Normal_Unspecified);
182					Action Pass_Up_CC_Cancel;
183					Action Stop_T_CCBS1;
184					Action Stop_Extended_T_CCBS1;
185					Action Stop_T_SUPERVISION;
186					Action Set_Selfdestruct;
187					Next_State CC_STATE_IDLE;
188				}
189			}
190		}
191		Stimulus CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1 {
192			Action Reset_A_Status;
193			Action Raw_Status_Count_Reset;
194		}
195		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
196			Action Pass_Up_CC_Cancel;
197			Action Send_CCBSErase(T_CCBS2_TIMEOUT);
198			Action Stop_T_CCBS1;
199			Action Stop_Extended_T_CCBS1;
200			Action Stop_T_SUPERVISION;
201			Action Set_Selfdestruct;
202			Next_State CC_STATE_IDLE;
203		}
204		Stimulus CC_EVENT_LINK_CANCEL {
205			Action Pass_Up_CC_Cancel;
206			Action Send_CCBSErase(Normal_Unspecified);
207			Action Stop_T_CCBS1;
208			Action Stop_Extended_T_CCBS1;
209			Action Stop_T_SUPERVISION;
210			Action Set_Selfdestruct;
211			Next_State CC_STATE_IDLE;
212		}
213		Stimulus CC_EVENT_CANCEL {
214			Action Send_CCBSErase(Normal_Unspecified);
215			Action Stop_T_CCBS1;
216			Action Stop_Extended_T_CCBS1;
217			Action Stop_T_SUPERVISION;
218			Action Set_Selfdestruct;
219			Next_State CC_STATE_IDLE;
220		}
221	}
222	State CC_STATE_B_AVAILABLE {
223		/* A status is always invalid on entry. */
224		Stimulus CC_EVENT_RECALL {
225			Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
226			Action Set_Call_To_Hangup;
227		}
228		Stimulus CC_EVENT_A_STATUS {
229			Action Stop_Extended_T_CCBS1;
230			Action Start_Extended_T_CCBS1;
231			Action Pass_Up_Status_Rsp_A_Indirect;
232		}
233		Stimulus CC_EVENT_A_FREE {
234			Action Send_RemoteUserFree;
235			Action Set_Raw_A_Status_Free;
236			//Action Promote_Raw_A_Status;
237			//Action Pass_Up_A_Status;
238			Test = Get_Extended_T_CCBS1_Status;
239			Test == Active {
240				Action Pass_Up_Status_Rsp_A;
241			}
242			Action Stop_T_CCBS1;
243			Action Stop_Extended_T_CCBS1;
244			/* Start T_CCBS3 */
245			Action Start_T_RECALL;
246			Next_State CC_STATE_WAIT_CALLBACK;
247		}
248		Stimulus CC_EVENT_A_BUSY {
249			Action Add_Raw_A_Status_Busy;
250			Test = Get_Extended_T_CCBS1_Status;
251			Test == Active {
252				Action Pass_Up_Status_Rsp_A;
253			}
254		}
255		Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
256			Test = Get_Raw_A_Status;
257			Test != Invalid {
258				/* Only received User A is busy. */
259				Action Raw_Status_Count_Reset;
260				Action Send_CCBSBFree;
261				Action Promote_Raw_A_Status;
262				Action Pass_Up_A_Status;
263				/* Optimization due to flattening */
264				//Test = Get_T_CCBS1_Status;
265				//Test != Active
266				{
267					Action Reset_Raw_A_Status;
268					Action Send_CCBSStatusRequest;
269					Action Start_T_CCBS1;
270				}
271				Next_State CC_STATE_SUSPENDED;
272			}
273			Test == Invalid {
274				/* Did not get any responses. */
275				Action Raw_Status_Count_Increment;
276				Test = Get_Raw_Status_Count;
277				Test >= RAW_STATUS_COUNT_MAX {
278					/* User A no longer present. */
279					Action Send_CCBSErase(Normal_Unspecified);
280					Action Pass_Up_CC_Cancel;
281					Action Stop_T_CCBS1;
282					Action Stop_Extended_T_CCBS1;
283					Action Stop_T_SUPERVISION;
284					Action Set_Selfdestruct;
285					Next_State CC_STATE_IDLE;
286				}
287				//Action Reset_Raw_A_Status;
288				Action Send_CCBSStatusRequest;
289				Action Start_T_CCBS1;
290			}
291		}
292		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
293			Action Pass_Up_CC_Cancel;
294			Action Send_CCBSErase(T_CCBS2_TIMEOUT);
295			Action Stop_T_CCBS1;
296			Action Stop_Extended_T_CCBS1;
297			Action Stop_T_SUPERVISION;
298			Action Set_Selfdestruct;
299			Next_State CC_STATE_IDLE;
300		}
301		Stimulus CC_EVENT_LINK_CANCEL {
302			Action Pass_Up_CC_Cancel;
303			Action Send_CCBSErase(Normal_Unspecified);
304			Action Stop_T_CCBS1;
305			Action Stop_Extended_T_CCBS1;
306			Action Stop_T_SUPERVISION;
307			Action Set_Selfdestruct;
308			Next_State CC_STATE_IDLE;
309		}
310		Stimulus CC_EVENT_CANCEL {
311			Action Send_CCBSErase(Normal_Unspecified);
312			Action Stop_T_CCBS1;
313			Action Stop_Extended_T_CCBS1;
314			Action Stop_T_SUPERVISION;
315			Action Set_Selfdestruct;
316			Next_State CC_STATE_IDLE;
317		}
318	}
319	State CC_STATE_SUSPENDED {
320		Stimulus CC_EVENT_RECALL {
321			Action Send_Error_Recall(ROSE_ERROR_CCBS_NotReadyForCall);
322			Action Set_Call_To_Hangup;
323		}
324		Stimulus CC_EVENT_A_STATUS {
325			Action Stop_Extended_T_CCBS1;
326			Action Start_Extended_T_CCBS1;
327			Action Pass_Up_Status_Rsp_A_Indirect;
328		}
329		Stimulus CC_EVENT_A_FREE {
330			Action Set_Raw_A_Status_Free;
331			Action Promote_Raw_A_Status;
332			Action Pass_Up_A_Status;
333			Test = Get_Extended_T_CCBS1_Status;
334			Test == Active {
335				Action Pass_Up_Status_Rsp_A;
336			}
337			Action Stop_T_CCBS1;
338			Action Stop_Extended_T_CCBS1;
339			Action Reset_A_Status;
340			Action Raw_Status_Count_Reset;
341			Next_State CC_STATE_ACTIVATED;
342		}
343		Stimulus CC_EVENT_A_BUSY {
344			Action Add_Raw_A_Status_Busy;
345			Test = Get_Extended_T_CCBS1_Status;
346			Test == Active {
347				Action Pass_Up_Status_Rsp_A;
348			}
349		}
350		Stimulus CC_EVENT_TIMEOUT_T_CCBS1 {
351			Test = Get_Raw_A_Status;
352			Test != Invalid {
353				/* Only received User A is busy. */
354				Action Raw_Status_Count_Reset;
355			}
356			Test == Invalid {
357				/* Did not get any responses. */
358				Action Raw_Status_Count_Increment;
359				Test = Get_Raw_Status_Count;
360				Test >= RAW_STATUS_COUNT_MAX {
361					/* User A no longer present. */
362					Action Send_CCBSErase(Normal_Unspecified);
363					Action Pass_Up_CC_Cancel;
364					Action Stop_T_CCBS1;
365					Action Stop_Extended_T_CCBS1;
366					Action Stop_T_SUPERVISION;
367					Action Set_Selfdestruct;
368					Next_State CC_STATE_IDLE;
369				}
370			}
371			Action Reset_Raw_A_Status;
372			Action Send_CCBSStatusRequest;
373			Action Start_T_CCBS1;
374		}
375		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
376			Action Pass_Up_CC_Cancel;
377			Action Send_CCBSErase(T_CCBS2_TIMEOUT);
378			Action Stop_T_CCBS1;
379			Action Stop_Extended_T_CCBS1;
380			Action Stop_T_SUPERVISION;
381			Action Set_Selfdestruct;
382			Next_State CC_STATE_IDLE;
383		}
384		Stimulus CC_EVENT_LINK_CANCEL {
385			Action Pass_Up_CC_Cancel;
386			Action Send_CCBSErase(Normal_Unspecified);
387			Action Stop_T_CCBS1;
388			Action Stop_Extended_T_CCBS1;
389			Action Stop_T_SUPERVISION;
390			Action Set_Selfdestruct;
391			Next_State CC_STATE_IDLE;
392		}
393		Stimulus CC_EVENT_CANCEL {
394			Action Send_CCBSErase(Normal_Unspecified);
395			Action Stop_T_CCBS1;
396			Action Stop_Extended_T_CCBS1;
397			Action Stop_T_SUPERVISION;
398			Action Set_Selfdestruct;
399			Next_State CC_STATE_IDLE;
400		}
401	}
402	State CC_STATE_WAIT_CALLBACK {
403		Stimulus CC_EVENT_TIMEOUT_T_RECALL {
404			Action Pass_Up_CC_Cancel;
405			Action Send_CCBSErase(T_CCBS3_TIMEOUT);
406			Action Stop_T_RECALL;
407			Action Stop_T_SUPERVISION;
408			Action Set_Selfdestruct;
409			Next_State CC_STATE_IDLE;
410		}
411		Stimulus CC_EVENT_STOP_ALERTING {
412			/*
413			 * If an earlier link can send us this event then we
414			 * really should be configured for globalRecall like
415			 * the earlier link.
416			 */
417			Test = Get_Recall_Mode;
418			Test == globalRecall {
419				Action Send_CCBSStopAlerting;
420			}
421			Action Stop_T_RECALL;
422			Action Reset_A_Status;
423			Action Raw_Status_Count_Reset;
424			Next_State CC_STATE_ACTIVATED;
425		}
426		Stimulus CC_EVENT_RECALL {
427			Action Pass_Up_CC_Call;
428			Action Set_Original_Call_Parameters;
429			Test = Get_Recall_Mode;
430			Test == globalRecall {
431				Action Send_CCBSStopAlerting;
432			}
433			Action Stop_T_RECALL;
434			Next_State CC_STATE_CALLBACK;
435		}
436		Stimulus CC_EVENT_A_STATUS {
437			Action Set_Raw_A_Status_Free;
438			Action Pass_Up_Status_Rsp_A_Indirect;
439		}
440		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
441			Action Pass_Up_CC_Cancel;
442			Action Send_CCBSErase(T_CCBS2_TIMEOUT);
443			Action Stop_T_RECALL;
444			Action Stop_T_SUPERVISION;
445			Action Set_Selfdestruct;
446			Next_State CC_STATE_IDLE;
447		}
448		Stimulus CC_EVENT_LINK_CANCEL {
449			Action Pass_Up_CC_Cancel;
450			Action Send_CCBSErase(Normal_Unspecified);
451			Action Stop_T_RECALL;
452			Action Stop_T_SUPERVISION;
453			Action Set_Selfdestruct;
454			Next_State CC_STATE_IDLE;
455		}
456		Stimulus CC_EVENT_CANCEL {
457			Action Send_CCBSErase(Normal_Unspecified);
458			Action Stop_T_RECALL;
459			Action Stop_T_SUPERVISION;
460			Action Set_Selfdestruct;
461			Next_State CC_STATE_IDLE;
462		}
463	}
464	State CC_STATE_CALLBACK {
465		Stimulus CC_EVENT_RECALL {
466			Action Send_Error_Recall(ROSE_ERROR_CCBS_AlreadyAccepted);
467			Action Set_Call_To_Hangup;
468		}
469		Stimulus CC_EVENT_A_STATUS {
470			Action Set_Raw_A_Status_Free;
471			Action Pass_Up_Status_Rsp_A_Indirect;
472		}
473		Stimulus CC_EVENT_TIMEOUT_T_SUPERVISION {
474			Action Pass_Up_CC_Cancel;
475			Action Send_CCBSErase(T_CCBS2_TIMEOUT);
476			Action Stop_T_SUPERVISION;
477			Action Set_Selfdestruct;
478			Next_State CC_STATE_IDLE;
479		}
480		Stimulus CC_EVENT_LINK_CANCEL {
481			Action Pass_Up_CC_Cancel;
482			Action Send_CCBSErase(Normal_Unspecified);
483			Action Stop_T_SUPERVISION;
484			Action Set_Selfdestruct;
485			Next_State CC_STATE_IDLE;
486		}
487		Stimulus CC_EVENT_CANCEL {
488			Action Send_CCBSErase(Normal_Unspecified);
489			Action Stop_T_SUPERVISION;
490			Action Set_Selfdestruct;
491			Next_State CC_STATE_IDLE;
492		}
493	}
494}
495