home *** CD-ROM | disk | FTP | other *** search
/ Telecom / 1996-04-telecom-walnutcreek.iso / technical / pager.ixo.example < prev    next >
Internet Message Format  |  1991-08-21  |  13KB

  1. From telecom@eecs.nwu.edu Tue Aug 20 23:17:45 1991
  2. Received: from delta.eecs.nwu.edu by gaak.LCS.MIT.EDU via TCP with SMTP
  3.     id AA21147; Tue, 20 Aug 91 23:17:39 EDT
  4. Resent-Message-Id: <9108210317.AA21147@gaak.LCS.MIT.EDU>
  5. Received: from NRI.RESTON.VA.US by delta.eecs.nwu.edu id aa09803;
  6.           20 Aug 91 16:08 CDT
  7. Received: from mcimail.com by NRI.NRI.Reston.VA.US id bo17715;
  8.           20 Aug 91 16:49 EDT
  9. Date: Tue, 20 Aug 91 20:40 GMT
  10. From: "J. Brad Hicks" <0004073044@mcimail.com>
  11. To: Pat Townson <telecom@eecs.nwu.edu>
  12. Subject: IXO.example
  13. Message-Id: <23910820204032/0004073044NC5EM@mcimail.com>
  14. Resent-Date:  Tue, 20 Aug 91 22:21:01 CDT
  15. Resent-From: telecom@eecs.nwu.edu
  16. Resent-To: ptownson@gaak.LCS.MIT.EDU
  17. Status: RO
  18.  
  19. IXO PROTOCOL EXAMPLE
  20.  
  21. Author:    J. Brad Hicks
  22. Language:  HyperTalk
  23. Rev. Date: 20 Aug 91
  24.  
  25.  
  26. The following two HyperTalk functions implement the IXO/TAP protocol
  27. sufficiently to handle numeric paging.  To use these scripts in HyperCard
  28. or SyperCard, place them in the stack/project script, then call them using:
  29.  
  30.    DialPager param1,param2,param3
  31.  
  32. where param1 is the modem phone number of the local paging company, param2
  33. is the phone number for the pager you want to beep, and param3 is the
  34. message to appear on the pager.
  35.  
  36. For debugging purposes, everything sent back from the modem is stored in
  37. global variable SaveBuffer.
  38.  
  39. CONSTRAINTS: In the above example, param2 MUST be an eight-digit number
  40. with no punctuation, zero-padded on the left ... or so I was told by the
  41. tech support gurus at CyberTel Paging.  If you are paging a numeric pager,
  42. param3 must be 1 to 12 bytes, and can contain any digit, a dash, or a
  43. space.  The gurus at CyberTel told me that it can contain asterisks and
  44. pound signs, but they don't work on my pager.  If you are paging an
  45. alphabetic pager, then param3 can contain any printable ASCII characters
  46. (32 to 126 decimal) and can be up to 120 bytes long.
  47.  
  48. REQUIREMENTS:  You will also need four of the HyperCard XCMDs/XFCNs for
  49. serial port control: configureSPort, recvUpTo, sendSPort, and closeSPort.
  50. These commands are all availabe via the "HyperCard Serial ToolKit" from
  51. APDA.  For those of you who are translating this into other languages,
  52. those all do what you'd expect except for recvUpTo, which takes three
  53. parameters.  Param1 is the byte to stop at; if "", then it runs until it
  54. times out.  Param2 is the maximum wait time, in 60ths of a second.  Param3
  55. is optional, and if it's anything but empty then it gets inserted before
  56. the serial port data.
  57.  
  58. IMPLEMENTATION LIMITS:  The IXO/TAP protocol supports sending multiple
  59. messages and multiple phone numbers in a single transaction.  Since I
  60. didn't need it for my purposes, I didn't implement them.  If you feel
  61. brave (and have the cooperation of your local paging company), you can
  62. send a theoretically infinite number of pager id/message packets in a
  63. single phone call by ending every packet except the last one with <ETB>
  64. instead of <ETX>.
  65.  
  66. NOTE TO HYPERCARD/SUPERCARD USERS:  Since this version of this file was put
  67. together to be distributed over non-Macintosh systems, the line-
  68. continuation character (option-return) has been stripped off of the longer
  69. lines.  I'm giving you credit for figuring out where it belongs; the
  70. continuation lines are indented (as per SuperCard format).
  71.  
  72. NOTE TO SUPERCARD USERS:  SuperCard predefines a constant CR that means the
  73. same thing as when I use it, so delete it from the global variable lists
  74. and delete the line where I initialize it at the top of DialPager.
  75.  
  76. CREDITS:  Thanks to Brent Chapman of Telebit for providing me with a copy
  77. of the IXO/TAP protocol spec.  The spec itself is excerpted from Glenayre
  78. Electronics' manual number GLP-3000-180, issue 5 (30 Jan 91), chapter 7,
  79. pages 7-1 to 7-13, and may be available from them at 1-604-263-1611.  The
  80. HyperCard Serial Toolkit is provided by Apple, and available through the
  81. Apple Programmers and Developers Assocation (APDA).  All other code was
  82. written by Brad Hicks at MasterCard International.
  83.  
  84. CONTACTING THE AUTHOR:  J. Brad Hicks can be most reliably contacted via
  85. MCI Mail at JBHICKS or Internet to the same address, jbhicks@mcimail.com.
  86. CompuServe users can also send mail to 76012,300.  AppleLink subscribers
  87. can send mail to B0186.  Via US mail, send to 12364 Spanish Trace Dr., Apt.
  88. G, Maryland Heights, MO 63043-2354, USA. Absolute last-ditch efforts only
  89. may be made to 1-314-275-3645, roughly 8:30 am to 5:30 pm Central Time
  90. (UCT+6).
  91.  
  92. DISCLAIMER:  This script is provided as-is and for free, and warranted
  93. to be worth at least that much.  Although I developed it while at
  94. MasterCard, neither MasterCard International nor its membership endorses
  95. this product.  The author denies responsibility for any consequences,
  96. positive or negative, arising out of anybody's use of this code, or any
  97. work derived from this code.  Test thoroughly.  Protect yourself.
  98. _______________________________________________________________________
  99.  
  100. on DialPager PhoneNumber,PagerID,theMessage
  101.   global SPortGlobals
  102.   global SaveBuffer
  103.   global STX,ETX,EOT,ACK,CR,NAK,ESC,RS
  104.   -- load constants
  105.   put numToChar(02) into STX
  106.   put numToChar(03) into ETX
  107.   put numToChar(04) into EOT
  108.   put numToChar(06) into ACK
  109.   put numToChar(13) into CR
  110.   put numToChar(21) into NAK
  111.   put numToChar(27) into ESC
  112.   put numToChar(30) into RS
  113.   -- initialize variables
  114.   put empty into SaveBuffer
  115.   put MsgPacket(PagerID,theMessage) into theMsgPacket
  116.   put 1 into OverAllAttempts
  117.   put false into OverAllSuccess
  118.   -- initialize port, modem
  119.   configureSPort "modemPort","baud300","stop10","parityEven","data7",
  120.     "XOnOutOff","CTSOutOff","lineFeedsOff","echoOff","editOff",
  121.     "stripOn","stripControlsOff","autoWrapOff"
  122.   sendSPort "ATZ" & CR
  123.   get recvUpTo(empty,60,empty) -- and throw it away
  124.   repeat until OverAllSuccess or (OverAllAttempts > 5)
  125.     put "Attempt #" & OverAllAttempts && "Status: " into the message
  126.     -- hang up, dial modem
  127.     put false into DialSuccess
  128.     put false into DialFailure
  129.     put "Dialing" after the message
  130.     sendSPort "+++"
  131.     wait 1 second
  132.     sendSPort "ATH" & CR
  133.     get recvUpTo(empty,120,empty)
  134.     put it after SaveBuffer
  135.     sendSPort "ATM0DT" & PhoneNumber & CR
  136.     put the seconds + 30 into TimeOut
  137.     repeat until DialSuccess or DialFailure
  138.       get recvUpTo(CR,1800,empty)
  139.       put it after SaveBuffer
  140.       if it contains "CONNECT" then put true into DialSuccess
  141.       else if it contains "NO CARRIER" then
  142.         put true into DialFailure
  143.         put "No Carrier" into FailureReason
  144.       else if it contains "ERROR" then
  145.         put true into DialFailure
  146.         put "Unknown Error" into FailureReason
  147.       else if it contains "NO DIALTONE" then
  148.         put true into DialFailure
  149.         put "No Dialtone!" into FailureReason
  150.       else if it contains "BUSY" then
  151.         put true into DialFailure
  152.         put "Busy" into FailureReason
  153.       else if it contains "NO ANSWER" then
  154.         put true into DialFailure
  155.         put "No Answer" into DialFailure
  156.       else if it contains "VOICE" then
  157.         put true into DialFailure
  158.         put "Wrong Number! (Voice Answered)"
  159.           into last word of the message
  160.         exit to HyperCard
  161.       else if the seconds >= TimeOut then
  162.         put true into DialFailure
  163.         put "Timed Out" into FailureReason
  164.       end if
  165.     end repeat
  166.     if DialFailure then
  167.       put FailureReason into last word of the message
  168.     else
  169.       put "DialSuccess, Waiting" into last word of the message
  170.       -- whack CR, wait for "ID="
  171.       put the seconds + 10 into TimeOut
  172.       put true into IDSuccess
  173.       put false into IDFailure
  174.       put empty into TempBuffer
  175.       repeat until IDSuccess or IDFailure
  176.         sendSPort CR
  177.         put recvUpTo(empty,90,TempBuffer) into TempBuffer
  178.         if TempBuffer contains "ID=" then put true into IDSuccess
  179.         else if the seconds >= timeOut then put true into IDFailure
  180.       end repeat
  181.       put TempBuffer after SaveBuffer
  182.       if IDSuccess then
  183.         put false into LoginACKed
  184.         put false into HangUp
  185.         put 1 into LoginAttempts
  186.         repeat until LoginACKed or HangUp or (LoginAttempts > 5)
  187.           -- indicate paging, wait for ACK/NAK
  188.           put "LogOn" into last word of the message
  189.           sendSPort ESC & "PG1" & CR
  190.           put the seconds + 10 into TimeOut
  191.           put false into LoginACKed
  192.           put false into LoginNAKed
  193.           put false into TimeOutExceeded
  194.           put false into HangUp
  195.           put empty into TempBuffer
  196.           repeat until LoginACKed or LoginNAKed
  197.             or TimeOutExceeded or HangUp
  198.             put recvUpTo(empty,90,TempBuffer) into TempBuffer
  199.             if TempBuffer contains (CR & ACK & CR) then
  200.               put true into LoginACKed
  201.             else if TempBuffer contains (CR & NAK & CR) then
  202.               put true into LoginNAKed
  203.             else if TempBuffer contains (CR & ESC & EOT & CR) then
  204.               put true into HangUp
  205.             else if the seconds >= timeOut then
  206.               put true into TimeOutExceeded
  207.             end if
  208.           end repeat
  209.           put TempBuffer after SaveBuffer
  210.           add 1 to LoginAttempts
  211.         end repeat
  212.         if LoginACKed then
  213.           put false into MsgACKed
  214.           put false into HangUp
  215.           put 1 into SendAttempts
  216.           put "LoggedIn, Sending" into last word of the message
  217.           repeat until MsgACKed or HangUp or (SendAttempts > 5)
  218.             -- send message, wait for ACK/NAK
  219.             sendSPort theMsgPacket
  220.             put the seconds + 10 into TimeOut
  221.             put false into MsgACKed
  222.             put false into MsgNAKed
  223.             put false into MsgInvalid
  224.             put false into TimeOutExceeded
  225.             put false into HangUp
  226.             put empty into TempBuffer
  227.             repeat until MsgACKed or MsgNAKed or TimeOutExceeded or HangUp
  228.               put recvUpTo(empty,90,TempBuffer) into TempBuffer
  229.               if TempBuffer contains (CR & ACK & CR) then
  230.                 put true into MsgACKed
  231.               else if TempBuffer contains (CR & NAK & CR) then
  232.                 put true into MsgNAKed
  233.               else if TempBuffer contains (CR & RS & CR) then
  234.                 put true into MsgInvalid
  235.               else if TempBuffer contains (CR & ESC & EOT & CR) then
  236.                 put true into HangUp
  237.               else if the seconds >= timeOut then
  238.                 put true into TimeOutExceeded
  239.               end if
  240.             end repeat
  241.             if MsgACKed then
  242.               put true into OverAllSuccess
  243.               put ", Success!" after the message
  244.             else
  245.               put ", Failure" after the message
  246.             end if
  247.             put TempBuffer after SaveBuffer
  248.             add 1 to SendAttempts
  249.           end repeat
  250.         else if HangUp then
  251.           put "CyberTelHungUp!" into last word of the message
  252.         else
  253.           put "LoginFailed!" into last word of the message
  254.         end if
  255.       end if
  256.     end if
  257.     -- hang up
  258.     sendSPort EOT & CR
  259.     put the seconds + 10 into TimeOut
  260.     put false into EOTrcvd
  261.     put false into TimeOutExceeded
  262.     put empty into TempBuffer
  263.     repeat until EOTrcvd or TimeOutExceeded
  264.       put recvUpTo(empty,90,TempBuffer) into TempBuffer
  265.       if TempBuffer contains (ESC & EOT & CR) then put true into EOTrcvd
  266.       else if the seconds >= timeOut then put true into TimeOutExceeded
  267.     end repeat
  268.     put TempBuffer after SaveBuffer
  269.     sendSPort "+++"
  270.     wait 1 second
  271.     sendSPort "ATH" & CR
  272.     get recvUpTo(empty,60,empty)
  273.     put it after SaveBuffer
  274.     add 1 to OverAllAttempts
  275.   end repeat
  276.   closeSPort
  277.   put empty into the message
  278. end DialPager
  279.  
  280. function MsgPacket PagerID,theMessage
  281.   global STX,ETX,EOT,ACK,CR,NAK,ESC,RS
  282.   -- strip illegal characters from PagerID
  283.   repeat with i = the length of PagerID down to 1
  284.     get char i of PagerID
  285.     if not (it is in "0123456789") then delete char i of PagerID
  286.   end repeat
  287.   -- left-pad to 8 digits
  288.   -- recommended by CyberTel, not in IXO spec
  289.   get 8 - the length of PagerID
  290.   repeat with i = 1 to it
  291.     put "0" before PagerID
  292.   end repeat
  293.   -- clean, trim theMessage
  294.   -- NOTE: edit code below assumes numeric pager;
  295.   --       alpha pagers accept all printable ASCII,
  296.   --       up to 120 bytes per message.
  297.   repeat with i = the length of theMessage down to 1
  298.     get char i of theMessage
  299.     if not (it is in "0123456789*#- ") then delete char i of theMessage
  300.   end repeat
  301.   get char 1 to 12 of theMessage
  302.   put it into theMessage
  303.   -- assemble message packet
  304.   put STX & PagerID & CR & theMessage & CR & ETX into TempPacket
  305.   -- calculate checkSum
  306.   put 0 into checkSum
  307.   repeat with i = 1 to the length of TempPacket
  308.     add charToNum(char i of TempPacket) to checkSum
  309.   end repeat
  310.   put numToChar((checkSum div 256) mod 16 + 48) into checkSumString
  311.   put numToChar((checkSum div 16) mod 16 + 48) after checkSumString
  312.   put numToChar(checkSum mod 16 + 48) after checkSumString
  313.   -- append checksum to packet
  314.   put checkSumString & CR after TempPacket
  315.   return TempPacket
  316. end MsgPacket
  317.  
  318.