HyperAppleTalk 4
Volume Number: 5
Issue Number: 4
Column Tag: HyperChat™
Related Info: AppleTalk Mgr
XCMD Corner: HyperAppleTalk IV
By Donald Koscheka, Arthur Young & Co., MacTutor Contributing Editor
Note: Source code files accompanying article are located on MacTech CD-ROM or
source code disks.
I sometimes think that, to most programmers, the network is best left to the
handful of specialists that ply their craft on this arcane art.
Think of the network as adding a new dimension to your programs, much as
perspective enabled medieval artists to add depth and realism to their paintings. While
many artists may have scoffed at perspective, I have no trouble believing that the
populace was awed by its discovery. Perhaps networking will shine the same light as
we enter the renaissance of computer programming.
If you’ve been following this column over the last three months, you may be
asking yourself, “Are we there yet?” This month, we tie the pieces together by
introducing the rest of AppleTalk XCMDs. I apologize for publishing listings last month
that you can’t really use until this month. I hope this issue makes up for it and in the
future I will do my best to provide “soup to nuts” code in each issue.
Conceptually, an AppleTalk interface can be reduced to the six steps: (1) Open
access to the transaction protocol and allocate any memory that will be needed to
interface to it. I chose the AppleTalk Data Stream Protocol(ADSP). ADSPOpen hooks us
up to ADSP, establishes a connection listener and returns the connection listener’s
socket address to Hypercard. NBPOpen initializes a data structure that we use to
interface to NBP. The January ’89 issue of this column provides the code for these
XCMDs.
(2) Given the address of the connection listener, register a name and type with
the network using the name binding protocol. Once registered, our entity’s name and
address will be listed in the “ directory”.
(3) If we want to be able to “dial up” other entities, we next perform a lookup
which returns all current names in the lookup table which acts just like a directory.
The names are returned as a list of items to Hypercard without their addresses. This
step is optional, if all you expect to do is respond to requests (as in the case of a
server), then you don’t need to know the names of the requesting entities.
(4) To call another entity, invoke the ADSPCall XCMD with the entity’s name.
ADSPCall extracts the network address from the lookup table using the routine
“NBPGetAddress”. This technique allows us to de-couple names and addresses; your
stacks need never be concerned with the address of an entity, the name is sufficient at
the Hypercard script level.
(5) Once a connection is established with another entity (called the remote end),
you send information to that entity using ADSPTalk. You receive information from the
remote end using ADSPListen. ADSPListen is the heart of the interface, in addition to
checking for incoming messages, it also monitors the status of all open connections.
(6) When the session completes, remove your name from the names table using
the NBPUnregister XFCN. Once unregistered, close down the interface to ADSP with the
ADSPClose and then close down your NBP interface with NBPClose.
--The XCMDS--
While the process is conceptually quite simple, the amount of code needed to
implement this interface may seem overwhelming. The rest of this article focuses on
ADSPCall, ADSPTalk, ADSPListen and ADSPHangup. Information on both NBP and the
open and close xcmds are available in that last two installments of this column as well
as in recently published literature from APDA.
(1) ADSPCall
ADSPCall (listing 1) first extracts the address of the entity from the lookup
table using NBPGetAddress. If you pass it the name of a currently visible entity, you
have a reasonable assurance that the call will complete.
Upon retrieving the address, adspcall walks the connection list checking to see if
a connection already exists with the remote end. If not, it creates a connection by
calling DSPCreate.
Outgoing calls are placed asynchronously, control is passed back to Hypercard
while the call completes in the “background”. Asynchronous communications pays big
dividends, adspcall attempts to establish the connection as many times as you request
in the retry field. Waiting for a call to complete can “hang” the system, a
particularly uncomfortable state for the user. If for any reason, the remote end has
gone off line, Hypercard won’t be stuck with an unbearable delay waiting for the call to
timeout.
Outgoing calls, like all other transactions on the network, must be monitored by
the listener. ADSPListen detects when the remote end picks up the phone.
To invoke ADSPCall from your script, use the following command line:
--1
-- get the name of the entity from the lookup table.
-- We let HyperAppleTalk handle the defaults for
-- retry, interval and buffer size.
--
-- The two above globals will have been initialized by
-- NBPOpen and ADSPOpen respectively.
--
global globalNBPData, globalADSPData
ADSPCall theEntity
(2) ADSPTalk
Once a connection is established with a remote end, we can send messages to that
entity. Like ADSPCall, ADSPTalk uses NBPGetAddress to get the address given a name.
Because NBPGetAddress returns 0 if the name had no corresponding address in the
lookup table, we can determine whether we have a connection to the remote end.
ADSPTalk scans the connection list to match the address with that of an entity in our
connection list (pointed to bey adsp^.ends). AdspTalk calls DSPTalk (covered last
month) to send the information. Outgoing messages are also sent asynchronously so
that the user is not made to suffer any delays while the transmission completes.
Like ADSPCall, the method of invoking ADSPTalk is straightforward:
--2
-- “theEntity” is the name of the remote end that you
-- called using ADSPCall and the card field contains the
-- data that you wish to send to the remote end.
--
global globalNBPData, globalADSPData
ADSPTalk theEntity, card field “outgoing message”
(3) ADSPListen
The quality of any conversation depends more on the skill of the listener than that
of the talker. This is no less true for the network - talking is the easy part, the
listener does the hard part. Like any good listener, ADSPListen must perform several
tasks at once -- (1) Answer incoming calls, (2) Monitor the status of outgoing calls,
(3) Receive incoming messages and (4) periodically check the status of each
connection.
Putting ADSPListen in the idle method of a card or stack provides a method for
periodically checking up on each connection.
For each established connection an entry exists in our adsp^.ends list. While
most of the data stored in the connection (cn) block is for our own use, the network
keeps us apprised of the connection’s status via two records: the parameter block (pb)
and the connection control block (ccb). The parameter block behaves as it would for
any low-level I/O on the Macintosh, it is the interface to the ADSP device driver. The