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