home *** CD-ROM | disk | FTP | other *** search
- From telecom@eecs.nwu.edu Tue Aug 20 23:17:45 1991
- Received: from delta.eecs.nwu.edu by gaak.LCS.MIT.EDU via TCP with SMTP
- id AA21147; Tue, 20 Aug 91 23:17:39 EDT
- Resent-Message-Id: <9108210317.AA21147@gaak.LCS.MIT.EDU>
- Received: from NRI.RESTON.VA.US by delta.eecs.nwu.edu id aa09803;
- 20 Aug 91 16:08 CDT
- Received: from mcimail.com by NRI.NRI.Reston.VA.US id bo17715;
- 20 Aug 91 16:49 EDT
- Date: Tue, 20 Aug 91 20:40 GMT
- From: "J. Brad Hicks" <0004073044@mcimail.com>
- To: Pat Townson <telecom@eecs.nwu.edu>
- Subject: IXO.example
- Message-Id: <23910820204032/0004073044NC5EM@mcimail.com>
- Resent-Date: Tue, 20 Aug 91 22:21:01 CDT
- Resent-From: telecom@eecs.nwu.edu
- Resent-To: ptownson@gaak.LCS.MIT.EDU
- Status: RO
-
- IXO PROTOCOL EXAMPLE
-
- Author: J. Brad Hicks
- Language: HyperTalk
- Rev. Date: 20 Aug 91
-
-
- The following two HyperTalk functions implement the IXO/TAP protocol
- sufficiently to handle numeric paging. To use these scripts in HyperCard
- or SyperCard, place them in the stack/project script, then call them using:
-
- DialPager param1,param2,param3
-
- where param1 is the modem phone number of the local paging company, param2
- is the phone number for the pager you want to beep, and param3 is the
- message to appear on the pager.
-
- For debugging purposes, everything sent back from the modem is stored in
- global variable SaveBuffer.
-
- CONSTRAINTS: In the above example, param2 MUST be an eight-digit number
- with no punctuation, zero-padded on the left ... or so I was told by the
- tech support gurus at CyberTel Paging. If you are paging a numeric pager,
- param3 must be 1 to 12 bytes, and can contain any digit, a dash, or a
- space. The gurus at CyberTel told me that it can contain asterisks and
- pound signs, but they don't work on my pager. If you are paging an
- alphabetic pager, then param3 can contain any printable ASCII characters
- (32 to 126 decimal) and can be up to 120 bytes long.
-
- REQUIREMENTS: You will also need four of the HyperCard XCMDs/XFCNs for
- serial port control: configureSPort, recvUpTo, sendSPort, and closeSPort.
- These commands are all availabe via the "HyperCard Serial ToolKit" from
- APDA. For those of you who are translating this into other languages,
- those all do what you'd expect except for recvUpTo, which takes three
- parameters. Param1 is the byte to stop at; if "", then it runs until it
- times out. Param2 is the maximum wait time, in 60ths of a second. Param3
- is optional, and if it's anything but empty then it gets inserted before
- the serial port data.
-
- IMPLEMENTATION LIMITS: The IXO/TAP protocol supports sending multiple
- messages and multiple phone numbers in a single transaction. Since I
- didn't need it for my purposes, I didn't implement them. If you feel
- brave (and have the cooperation of your local paging company), you can
- send a theoretically infinite number of pager id/message packets in a
- single phone call by ending every packet except the last one with <ETB>
- instead of <ETX>.
-
- NOTE TO HYPERCARD/SUPERCARD USERS: Since this version of this file was put
- together to be distributed over non-Macintosh systems, the line-
- continuation character (option-return) has been stripped off of the longer
- lines. I'm giving you credit for figuring out where it belongs; the
- continuation lines are indented (as per SuperCard format).
-
- NOTE TO SUPERCARD USERS: SuperCard predefines a constant CR that means the
- same thing as when I use it, so delete it from the global variable lists
- and delete the line where I initialize it at the top of DialPager.
-
- CREDITS: Thanks to Brent Chapman of Telebit for providing me with a copy
- of the IXO/TAP protocol spec. The spec itself is excerpted from Glenayre
- Electronics' manual number GLP-3000-180, issue 5 (30 Jan 91), chapter 7,
- pages 7-1 to 7-13, and may be available from them at 1-604-263-1611. The
- HyperCard Serial Toolkit is provided by Apple, and available through the
- Apple Programmers and Developers Assocation (APDA). All other code was
- written by Brad Hicks at MasterCard International.
-
- CONTACTING THE AUTHOR: J. Brad Hicks can be most reliably contacted via
- MCI Mail at JBHICKS or Internet to the same address, jbhicks@mcimail.com.
- CompuServe users can also send mail to 76012,300. AppleLink subscribers
- can send mail to B0186. Via US mail, send to 12364 Spanish Trace Dr., Apt.
- G, Maryland Heights, MO 63043-2354, USA. Absolute last-ditch efforts only
- may be made to 1-314-275-3645, roughly 8:30 am to 5:30 pm Central Time
- (UCT+6).
-
- DISCLAIMER: This script is provided as-is and for free, and warranted
- to be worth at least that much. Although I developed it while at
- MasterCard, neither MasterCard International nor its membership endorses
- this product. The author denies responsibility for any consequences,
- positive or negative, arising out of anybody's use of this code, or any
- work derived from this code. Test thoroughly. Protect yourself.
- _______________________________________________________________________
-
- on DialPager PhoneNumber,PagerID,theMessage
- global SPortGlobals
- global SaveBuffer
- global STX,ETX,EOT,ACK,CR,NAK,ESC,RS
- -- load constants
- put numToChar(02) into STX
- put numToChar(03) into ETX
- put numToChar(04) into EOT
- put numToChar(06) into ACK
- put numToChar(13) into CR
- put numToChar(21) into NAK
- put numToChar(27) into ESC
- put numToChar(30) into RS
- -- initialize variables
- put empty into SaveBuffer
- put MsgPacket(PagerID,theMessage) into theMsgPacket
- put 1 into OverAllAttempts
- put false into OverAllSuccess
- -- initialize port, modem
- configureSPort "modemPort","baud300","stop10","parityEven","data7",
- "XOnOutOff","CTSOutOff","lineFeedsOff","echoOff","editOff",
- "stripOn","stripControlsOff","autoWrapOff"
- sendSPort "ATZ" & CR
- get recvUpTo(empty,60,empty) -- and throw it away
- repeat until OverAllSuccess or (OverAllAttempts > 5)
- put "Attempt #" & OverAllAttempts && "Status: " into the message
- -- hang up, dial modem
- put false into DialSuccess
- put false into DialFailure
- put "Dialing" after the message
- sendSPort "+++"
- wait 1 second
- sendSPort "ATH" & CR
- get recvUpTo(empty,120,empty)
- put it after SaveBuffer
- sendSPort "ATM0DT" & PhoneNumber & CR
- put the seconds + 30 into TimeOut
- repeat until DialSuccess or DialFailure
- get recvUpTo(CR,1800,empty)
- put it after SaveBuffer
- if it contains "CONNECT" then put true into DialSuccess
- else if it contains "NO CARRIER" then
- put true into DialFailure
- put "No Carrier" into FailureReason
- else if it contains "ERROR" then
- put true into DialFailure
- put "Unknown Error" into FailureReason
- else if it contains "NO DIALTONE" then
- put true into DialFailure
- put "No Dialtone!" into FailureReason
- else if it contains "BUSY" then
- put true into DialFailure
- put "Busy" into FailureReason
- else if it contains "NO ANSWER" then
- put true into DialFailure
- put "No Answer" into DialFailure
- else if it contains "VOICE" then
- put true into DialFailure
- put "Wrong Number! (Voice Answered)"
- into last word of the message
- exit to HyperCard
- else if the seconds >= TimeOut then
- put true into DialFailure
- put "Timed Out" into FailureReason
- end if
- end repeat
- if DialFailure then
- put FailureReason into last word of the message
- else
- put "DialSuccess, Waiting" into last word of the message
- -- whack CR, wait for "ID="
- put the seconds + 10 into TimeOut
- put true into IDSuccess
- put false into IDFailure
- put empty into TempBuffer
- repeat until IDSuccess or IDFailure
- sendSPort CR
- put recvUpTo(empty,90,TempBuffer) into TempBuffer
- if TempBuffer contains "ID=" then put true into IDSuccess
- else if the seconds >= timeOut then put true into IDFailure
- end repeat
- put TempBuffer after SaveBuffer
- if IDSuccess then
- put false into LoginACKed
- put false into HangUp
- put 1 into LoginAttempts
- repeat until LoginACKed or HangUp or (LoginAttempts > 5)
- -- indicate paging, wait for ACK/NAK
- put "LogOn" into last word of the message
- sendSPort ESC & "PG1" & CR
- put the seconds + 10 into TimeOut
- put false into LoginACKed
- put false into LoginNAKed
- put false into TimeOutExceeded
- put false into HangUp
- put empty into TempBuffer
- repeat until LoginACKed or LoginNAKed
- or TimeOutExceeded or HangUp
- put recvUpTo(empty,90,TempBuffer) into TempBuffer
- if TempBuffer contains (CR & ACK & CR) then
- put true into LoginACKed
- else if TempBuffer contains (CR & NAK & CR) then
- put true into LoginNAKed
- else if TempBuffer contains (CR & ESC & EOT & CR) then
- put true into HangUp
- else if the seconds >= timeOut then
- put true into TimeOutExceeded
- end if
- end repeat
- put TempBuffer after SaveBuffer
- add 1 to LoginAttempts
- end repeat
- if LoginACKed then
- put false into MsgACKed
- put false into HangUp
- put 1 into SendAttempts
- put "LoggedIn, Sending" into last word of the message
- repeat until MsgACKed or HangUp or (SendAttempts > 5)
- -- send message, wait for ACK/NAK
- sendSPort theMsgPacket
- put the seconds + 10 into TimeOut
- put false into MsgACKed
- put false into MsgNAKed
- put false into MsgInvalid
- put false into TimeOutExceeded
- put false into HangUp
- put empty into TempBuffer
- repeat until MsgACKed or MsgNAKed or TimeOutExceeded or HangUp
- put recvUpTo(empty,90,TempBuffer) into TempBuffer
- if TempBuffer contains (CR & ACK & CR) then
- put true into MsgACKed
- else if TempBuffer contains (CR & NAK & CR) then
- put true into MsgNAKed
- else if TempBuffer contains (CR & RS & CR) then
- put true into MsgInvalid
- else if TempBuffer contains (CR & ESC & EOT & CR) then
- put true into HangUp
- else if the seconds >= timeOut then
- put true into TimeOutExceeded
- end if
- end repeat
- if MsgACKed then
- put true into OverAllSuccess
- put ", Success!" after the message
- else
- put ", Failure" after the message
- end if
- put TempBuffer after SaveBuffer
- add 1 to SendAttempts
- end repeat
- else if HangUp then
- put "CyberTelHungUp!" into last word of the message
- else
- put "LoginFailed!" into last word of the message
- end if
- end if
- end if
- -- hang up
- sendSPort EOT & CR
- put the seconds + 10 into TimeOut
- put false into EOTrcvd
- put false into TimeOutExceeded
- put empty into TempBuffer
- repeat until EOTrcvd or TimeOutExceeded
- put recvUpTo(empty,90,TempBuffer) into TempBuffer
- if TempBuffer contains (ESC & EOT & CR) then put true into EOTrcvd
- else if the seconds >= timeOut then put true into TimeOutExceeded
- end repeat
- put TempBuffer after SaveBuffer
- sendSPort "+++"
- wait 1 second
- sendSPort "ATH" & CR
- get recvUpTo(empty,60,empty)
- put it after SaveBuffer
- add 1 to OverAllAttempts
- end repeat
- closeSPort
- put empty into the message
- end DialPager
-
- function MsgPacket PagerID,theMessage
- global STX,ETX,EOT,ACK,CR,NAK,ESC,RS
- -- strip illegal characters from PagerID
- repeat with i = the length of PagerID down to 1
- get char i of PagerID
- if not (it is in "0123456789") then delete char i of PagerID
- end repeat
- -- left-pad to 8 digits
- -- recommended by CyberTel, not in IXO spec
- get 8 - the length of PagerID
- repeat with i = 1 to it
- put "0" before PagerID
- end repeat
- -- clean, trim theMessage
- -- NOTE: edit code below assumes numeric pager;
- -- alpha pagers accept all printable ASCII,
- -- up to 120 bytes per message.
- repeat with i = the length of theMessage down to 1
- get char i of theMessage
- if not (it is in "0123456789*#- ") then delete char i of theMessage
- end repeat
- get char 1 to 12 of theMessage
- put it into theMessage
- -- assemble message packet
- put STX & PagerID & CR & theMessage & CR & ETX into TempPacket
- -- calculate checkSum
- put 0 into checkSum
- repeat with i = 1 to the length of TempPacket
- add charToNum(char i of TempPacket) to checkSum
- end repeat
- put numToChar((checkSum div 256) mod 16 + 48) into checkSumString
- put numToChar((checkSum div 16) mod 16 + 48) after checkSumString
- put numToChar(checkSum mod 16 + 48) after checkSumString
- -- append checksum to packet
- put checkSumString & CR after TempPacket
- return TempPacket
- end MsgPacket
-
-