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