1// -*- tab-width: 4; -*- 2 3%{ 4// 5// The contents of this file are subject to the Mozilla Public 6// License Version 1.1 (the "License"); you may not use this file 7// except in compliance with the License. You may obtain a copy of 8// the License at http://www.mozilla.org/MPL/ 9// 10// Software distributed under the License is distributed on an "AS 11// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 12// implied. See the License for the specific language governing 13// rights and limitations under the License. 14// 15// The Original Code is State Machine Compiler (SMC). 16// 17// The Initial Developer of the Original Code is Charles W. Rapp. 18// Portions created by Charles W. Rapp are 19// Copyright (C) 2000 - 2003 Charles W. Rapp. 20// All Rights Reserved. 21// 22// Contributor(s): 23// 24// Name 25// Telephone.sm 26// 27// Description 28// Runs a plain old telphone. That means the proper sounds at 29// the proper time. 30// 31// RCS ID 32// $Id: Telephone.sm,v 1.6 2005/06/08 11:09:13 cwrapp Exp $ 33// 34// CHANGE LOG 35// $Log: Telephone.sm,v $ 36// Revision 1.6 2005/06/08 11:09:13 cwrapp 37// + Updated Python code generator to place "pass" in methods with empty 38// bodies. 39// + Corrected FSM errors in Python example 7. 40// + Removed unnecessary includes from C++ examples. 41// + Corrected errors in top-level makefile's distribution build. 42// 43// Revision 1.5 2005/06/03 19:58:28 cwrapp 44// Further updates for release 4.0.0 45// 46// Revision 1.4 2005/05/28 13:51:24 cwrapp 47// Update Java examples 1 - 7. 48// 49// Revision 1.0 2003/12/14 20:22:53 charlesr 50// Initial revision 51// 52%} 53 54%class Telephone 55%start CallMap::OnHook 56%package smc_ex7 57 58%map CallMap 59%% 60 61OnHook 62Entry 63{ 64 updateClock(); 65 startClockTimer(); 66} 67Exit 68{ 69 stopTimer("ClockTimer"); 70} 71{ 72 // We are handling the caller's side of the connection. 73 OffHook 74 Dialing/push(PhoneNumber::DialTone) 75 { 76 clearDisplay(); 77 setReceiver("on hook", "Put down receiver"); 78 } 79 80 // Time to update the clock's display. 81 ClockTimer 82 nil 83 { 84 updateClock(); 85 startClockTimer(); 86 } 87} 88 89// The number is being dialed. 90Dialing 91{ 92 // Dialing successfully completed. 93 DialingDone(callType: int, areaCode: String, exchange: String, local: String) 94 Routing 95 { 96 routeCall(callType, areaCode, exchange, local); 97 } 98 99 // Dialing errors. 100 LeftOffHook 101 LeftOffHook 102 {} 103 104 InvalidDigit 105 InvalidDigit 106 {} 107} 108 109// The call is now being routed. 110Routing 111{ 112 Emergency 113 PlayingMessage 114 { 115 playEmergency(); 116 } 117 118 NYCTemp 119 NYCTemp 120 {} 121 122 Time 123 Time 124 {} 125 126 DepositMoney 127 DepositMoney 128 {} 129 130 LineBusy 131 BusySignal 132 {} 133 134 InvalidNumber 135 PlayingMessage 136 { 137 playInvalidNumber(); 138 } 139} 140 141NYCTemp 142Entry 143{ 144 loop("ringing"); 145 startTimer("RingTimer", 10000); 146} 147Exit 148{ 149 stopLoop("ringing"); 150} 151{ 152 RingTimer 153 PlayingMessage 154 { 155 playNYCTemp(); 156 } 157} 158 159Time 160Entry 161{ 162 loop("ringing"); 163 startTimer("RingTimer", 10000); 164} 165Exit 166{ 167 stopLoop("ringing"); 168} 169{ 170 RingTimer 171 PlayingMessage 172 { 173 playTime(); 174 } 175} 176 177DepositMoney 178Entry 179{ 180 loop("ringing"); 181 startTimer("RingTimer", 5000); 182} 183Exit 184{ 185 stopLoop("ringing"); 186} 187{ 188 RingTimer 189 PlayingMessage 190 { 191 playDepositMoney(); 192 } 193} 194 195BusySignal 196Entry 197{ 198 loop("busy"); 199} 200Exit 201{ 202 stopLoop("busy"); 203} 204{ 205 // Wait for on hook only. 206} 207 208PlayingMessage 209{ 210 // If caller hangs up while a message is being played, 211 // be sure to stop the playback. 212 OnHook 213 OnHook 214 { 215 stopPlayback(); 216 setReceiver("off hook", "Pick up receiver"); 217 clearDisplay(); 218 } 219 220 PlaybackDone 221 MessagePlayed 222 {} 223} 224 225MessagePlayed 226Entry 227{ 228 startTimer("OffHookTimer", 10000); 229} 230Exit 231{ 232 stopTimer("OffHookTimer"); 233} 234{ 235 OffHookTimer 236 LeftOffHook 237 {} 238} 239 240//--------------------------------------------------------------- 241// Error States. 242// 243// Let someone know the phone has been left off the hook. 244LeftOffHook 245Entry 246{ 247 startTimer("LoopTimer", 10000); 248 loop("phone_off_hook"); 249} 250Exit 251{ 252 stopTimer("LoopTimer"); 253 stopLoop("phone_off_hook"); 254} 255{ 256 LoopTimer 257 WaitForOnHook 258 {} 259 260 Default 261 nil 262 {} 263} 264 265InvalidDigit 266Entry 267{ 268 startTimer("LoopTimer", 10000); 269 loop("fast_busy"); 270} 271Exit 272{ 273 stopTimer("LoopTimer"); 274 stopLoop("fast_busy"); 275} 276{ 277 LoopTimer 278 WaitForOnHook 279 {} 280 281 Default 282 nil 283 {} 284} 285 286// Stay in this state until the telephone is on hook. 287WaitForOnHook 288{ 289 Default 290 nil 291 {} 292} 293 294Default 295{ 296 // Ignore any dialings after a phone number has been 297 // collected. 298 Digit(n : String) 299 nil 300 {} 301 302 DialingDone 303 nil 304 {} 305 306 InvalidDigit 307 nil 308 {} 309 310 // No matter when it happens, when the phone is hung 311 // up, this call is OVER! 312 OnHook 313 OnHook 314 { 315 setReceiver("off hook", "Pick up receiver"); 316 clearDisplay(); 317 } 318 319 // Ignore the clock timer outside of the OnHook state. 320 ClockTimer 321 nil 322 {} 323} 324%% 325 326// This map processes dialed digits. It either returns success 327// when 328%map PhoneNumber 329%% 330DialTone 331Entry 332{ 333 loop("dialtone"); 334 startTimer("OffHookTimer", 10000); 335} 336Exit 337{ 338 stopTimer("OffHookTimer"); 339 stopLoop("dialtone"); 340} 341{ 342 // If an invalid digit is dialed, give up collecting 343 // digits immediately. 344 Digit(n : String) 345 [Integer.parseInt(n) < 0 || 346 Integer.parseInt(n) > 9] 347 pop(InvalidDigit) 348 { 349 clearDisplay(); 350 } 351 352 // If the first digit is 1, then this is a long distance 353 // phone call. Don't save this first digit. 354 Digit(n : String) 355 [Integer.parseInt(n) == 1] 356 LongDistance 357 { 358 playTT(n); 359 setType(Telephone.LONG_DISTANCE); 360 saveAreaCode(n); 361 addDisplay("-"); 362 } 363 364 // Check for 911. 365 Digit(n : String) 366 [Integer.parseInt(n) == 9] 367 OneOneStart 368 { 369 playTT(n); 370 saveExchange(n); 371 } 372 373 Digit(n : String) 374 Exchange 375 { 376 playTT(n); 377 setType(Telephone.LOCAL); 378 saveExchange(n); 379 } 380} 381 382// Collect the area and then move on to the local number. 383LongDistance 384Entry 385{ 386 startTimer("OffHookTimer", 10000); 387} 388Exit 389{ 390 stopTimer("OffHookTimer"); 391} 392{ 393 // If an invalid digit is dialed, give up collecting 394 // digits immediately. 395 Digit(n : String) 396 [Integer.parseInt(n) < 0 || 397 Integer.parseInt(n) > 9] 398 pop(InvalidDigit) 399 { 400 clearDisplay(); 401 } 402 403 Digit(n : String) 404 [ctxt.getAreaCode().length() < 3] 405 nil 406 { 407 playTT(n); 408 saveAreaCode(n); 409 resetTimer("OffHookTimer"); 410 } 411 412 Digit(n : String) 413 Exchange 414 { 415 playTT(n); 416 saveAreaCode(n); 417 addDisplay("-"); 418 } 419} 420 421// Check if this is a 911 call. 422OneOneStart 423Entry 424{ 425 startTimer("OffHookTimer", 10000); 426} 427Exit 428{ 429 stopTimer("OffHookTimer"); 430} 431{ 432 // If an invalid digit is dialed, give up collecting 433 // digits immediately. 434 Digit(n : String) 435 [Integer.parseInt(n) < 0 || 436 Integer.parseInt(n) > 9] 437 pop(InvalidDigit) 438 { 439 clearDisplay(); 440 } 441 442 Digit(n : String) 443 [Integer.parseInt(n) == 1] 444 NineOne 445 { 446 playTT(n); 447 saveExchange(n); 448 } 449 450 Digit(n : String) 451 Exchange 452 { 453 playTT(n); 454 setType(Telephone.LOCAL); 455 saveExchange(n); 456 } 457} 458 459// Almost there. 460NineOne 461Entry 462{ 463 startTimer("OffHookTimer", 10000); 464} 465Exit 466{ 467 stopTimer("OffHookTimer"); 468} 469{ 470 // If an invalid digit is dialed, give up collecting 471 // digits immediately. 472 Digit(n : String) 473 [Integer.parseInt(n) < 0 || 474 Integer.parseInt(n) > 9] 475 pop(InvalidDigit) 476 { 477 clearDisplay(); 478 } 479 480 Digit(n : String) 481 [Integer.parseInt(n) == 1] 482 pop(DialingDone, 483 ctxt.getType(), 484 ctxt.getAreaCode(), 485 ctxt.getExchange(), 486 ctxt.getLocal()) 487 { 488 playTT(n); 489 setType(Telephone.EMERGENCY); 490 saveExchange(n); 491 } 492 493 Digit(n : String) 494 LocalCall 495 { 496 playTT(n); 497 setType(Telephone.LOCAL); 498 saveExchange(n); 499 addDisplay("-"); 500 } 501} 502 503// Collect the three digit exchange. 504Exchange 505Entry 506{ 507 startTimer("OffHookTimer", 10000); 508} 509Exit 510{ 511 stopTimer("OffHookTimer"); 512} 513{ 514 // If an invalid digit is dialed, give up collecting 515 // digits immediately. 516 Digit(n : String) 517 [Integer.parseInt(n) < 0 || 518 Integer.parseInt(n) > 9] 519 pop(InvalidDigit) 520 { 521 clearDisplay(); 522 } 523 524 Digit(n : String) 525 [ctxt.getExchange().length() < 2] 526 nil 527 { 528 playTT(n); 529 saveExchange(n); 530 resetTimer("OffHookTimer"); 531 } 532 533 Digit(n : String) 534 LocalCall 535 { 536 playTT(n); 537 saveExchange(n); 538 addDisplay("-"); 539 } 540} 541 542// Process a local call. 543LocalCall 544Entry 545{ 546 startTimer("OffHookTimer", 10000); 547} 548Exit 549{ 550 stopTimer("OffHookTimer"); 551} 552{ 553 // If an invalid digit is dialed, give up collecting 554 // digits immediately. 555 Digit(n : String) 556 [Integer.parseInt(n) < 0 || 557 Integer.parseInt(n) > 9] 558 pop(InvalidDigit) 559 { 560 clearDisplay(); 561 } 562 563 Digit(n : String) 564 [ctxt.getLocal().length() < 3] 565 nil 566 { 567 playTT(n); 568 saveLocal(n); 569 resetTimer("OffHookTimer"); 570 } 571 572 Digit(n : String) 573 pop(DialingDone, 574 ctxt.getType(), 575 ctxt.getAreaCode(), 576 ctxt.getExchange(), 577 ctxt.getLocal()) 578 { 579 playTT(n); 580 saveLocal(n); 581 } 582} 583 584Default 585{ 586 // Caller has stopped dialing and left the phone 587 // off hook. 588 OffHookTimer 589 pop(LeftOffHook) 590 { 591 clearDisplay(); 592 } 593 594 // Pass this event up. 595 OnHook 596 pop(OnHook) 597 { 598 clearDisplay(); 599 } 600 601 InvalidDigit 602 pop(InvalidDigit) 603 { 604 clearDisplay(); 605 } 606 607 // Ignore the clock timer outside of the OnHook state. 608 ClockTimer 609 nil 610 {} 611} 612 613%% 614