Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Networking /
Chapter 10 - Link-Access Protocol (LAP) Manager / Using the LAP Manager


How the LAP Manager Calls Your Transition Event
Handler Routine

This section describes how to write a transition event handler routine that responds to notification of AppleTalk transitions. Because the LAP Manager calls your transition event routine using C conventions, a transition event handler routine written in Pascal requires glue code to function correctly. To help solve this problem, this section includes a discussion of how to write a transition event routine using Pascal, and it also
includes glue code that you will need. This section also describes the standard AppleTalk transitions and how your routine can respond to a particular transition.

When you have used the LAPAddATQ function to add an entry to the AppleTalk Transition Queue, the LAP Manager calls the transition event handler routine, whose pointer you pass to the LAP Manager in the AppleTalk Transition Queue entry record, whenever an AppleTalk transition occurs.

Table 10-1 shows the standard AppleTalk transitions (each of which is discussed later in this section) and their constants and routine selectors.
Table 10-1 AppleTalk transitions and their constants and routine selectors
AppleTalk transitionConstantRoutine selector
OpenATTransOpen0
Prepare-to-closeATTransClose2
Permission-to-closeATTransClosePrep3
Cancel-closeATTransCancelCATTransCancelClose4
Network-connection- changeATTransNetworkTransition[2]5
Flagship-name-changeATTransNameChangeTellTask*6
Permission-to-change-
flagship-name
ATTransNameChangeAskTask*7
Cancel-flagship-name- changeATTransCancelNameChange*8
Cable-range-changeATTransCableChange*'rnge'
CPU-speed-changeATTransSpeedChange*'sped'

From assembly language, when the LAP Manager calls your routine, the stack looks
like this:

The first item on the stack (after the 4-byte-long return address) is a routine selector. There is one routine selector for each type of transition. Some transition events have a single-digit routine selector. Other transition events are four-character codes. Codes starting with an uppercase letter (A through Z) are reserved for use by developers. All other codes are reserved for use by Apple Computer, Inc.

The second item passed to your routine on the stack is a pointer to your routine's entry in the AppleTalk Transition Queue. You can use this pointer to gain access to any fields at the end of the queue entry that you allocated for your own use. The last item passed to your routine on the stack is a 4-byte-long parameter whose meaning depends on the type of transition.

With the exception of the open transition, the prepare-to-close transition, the flagship-
name-change transition, the permission-to-change-flagship-name transition, and the cancel-flagship-name transition, the interface between the AppleTalk Transition Queue and your routine must follow these conventions:

Again, these restrictions do not apply to the open transition, the prepare-to-close transition, and the three flagship-name transitions.

IMPORTANT
It is important that you return a 0 in the D0 register whenever you receive a transition event routine selector that you do not recognize or do not choose to handle. Returning a nonzero value in the D0 register might cause the system to cancel an attempt to close AppleTalk, for example, or it might be misinterpreted in some other way. You should only return a nonzero result to known transition events.

Writing a Transition Event Handler Routine Using Pascal

The LAP Manager assumes that you will use the CallAddr field of your event record to pass it a pointer to a transition event handler routine that is written in the C program-
ming language. The LAP Manager use C calling conventions when it calls your routine.

If you write your transition event handler routine in Pascal, you must include a glue code wrapper routine. You can use either the sample glue code provided in this section or your own method. To use this glue code, you must modify the AppleTalk Transition Queue entry record to include a field to hold a pointer to your Pascal transition event handler routine. You must add this field directly after the CallAddr field. You use the CallAddr field to pass the address of the assembly-language glue code routine. Here is the type declaration for an AppleTalk Transition Queue entry record that includes the additional field that is required if you use the glue code:

TYPE myATQEntry = 
RECORD
   qlink:         Ptr;              {ptr to next queue entry}
   qType:         Integer;          {reserved} 
   CallAddr:      ProcPtr;          {ptr to the glue code}
   PATQProcPtr:   ProcPtr;          {ptr to Pascal ATQ }
                                    { routine; this field must }
                                    { follow the CallAddr field. }
                                    { Do not change the order of }
                                    { these fields.}
   globs:         TransEventPtr;    {ptr to user defined globals} 
END;

myATQEntryPtr = ^myATQEntry;
myATQEntryHdl = ^myATQEntryPtr;
The following segment of code shows how to add an AppleTalk Transition Queue entry to the queue. In this example, the actual transition event handler routine is called ATQueueProc. The glue code routine is called CallTransQueue. The LAPAddATQ function passes the glue code routine to the LAP Manager in the CallAddr field of
the AppleTalk Transition Queue entry myATQEntry.

VAR
   gATQEntry: myATQEntry;
   OSErr: err;
BEGIN
   gATQEntry.CallAddr := ProcPtr(@CallTransQueue);
   gATQEntry.PATQProcPtr := ProcPtr(@ATQueueProc);
   err := LAPAddATQ(ATQEntryPtr(@gATQEntry));
Listing 10-4 shows the sample assembly-language glue code routine CallTransQueue that you can use if you write your transition event handler routine in Pascal. The glue routine takes the parameters from the stack and sets up a Pascal stack, then calls the function pointed to by the PATQProcPtr field of the AppleTalk Transition Queue entry record. On return, the glue code pulls the result from the stack and puts it into the D0 register, where the LAP Manager expects to find it.

Listing 10-4 Glue code for a Pascal transition event handler routine

;FUNCTION CallTransQueue (selector: LongInt; q: ATQEntryPtr;
;                         p: Ptr): LongInt; 
;EXTERNAL;

CallTransQueue PROCEXPORT
   LINK       A6,#$0000       ;set up a local stack frame
   CLR.L      -(A7)           ;set space for return result
   MOVE.L     $0008(A6),-(A7) ;move selector to stack
   MOVE.L     $000C(A6),-(A7) ;move ATQPtr to stack
   MOVEA.L    (A7),A0         ;put copy ATQPtr in A0
   MOVEA.L    $000A(A0),A0    ;put pointer to real ATQ in A0
   MOVE.L     $0010(A6),-(A7) ;move last parameter: 
                              ; pointer to stack
   JSR        (A0)            ;call the Pascal ATQ function
   MOVE.L     (A7)+,D0        ;move result into D0
   UNLK       A6              ;tear down local stack frame
   RTS                        ;return
   ENDP
   END

Open Transition

When an application calls the MPPOpen function or the Device Manager's OpenDriver function, AppleTalk attempts to open the .MPP driver. If the .MPP driver is already open, the LAP Manager does not call the AppleTalk Transition Queue transition event handler routines. If AppleTalk successfully opens the .MPP driver, the LAP Manager then calls every routine listed in the AppleTalk Transition Queue with an open transition (ATTransOpen).

When the LAP Manager calls your transition event handler routine, the stack looks
like this:

The last item on the stack for an open transition is a pointer to the start of the Device Manager extended parameter block used by the routine that opened the .MPP driver. This pointer is provided for your information only; you must not change any of the fields in this parameter block.

Your transition event handler routine can perform any tasks you wish in response to the notification that the .MPP driver has been opened, such as using the Name-Binding Protocol (NBP) to register a name on the internet. Return 0 in the D0 register to indicate that your routine executed with no error.

Note
The open transition event occurs at system task time, during which you can allocate memory.

Prepare-to-Close Transition

When any routine calls the MPPClose function or the Device Manager's CloseDriver function to close the .MPP driver, the LAP Manager calls every routine listed in the AppleTalk Transition Queue before the .MPP driver closes with an ATTransClose transition; if the .MPP driver is already closed when a routine calls either MPPClose or CloseDriver, the LAP Manager does not call the transition event handler routines in the AppleTalk Transition Queue.

When the system closes the .MPP driver
Whereas it is unlikely that opening the .MPP driver will adversely affect another program, an application should never close the .MPP driver because another program might be using it. Under certain circum-
stances, however, the system might close the .MPP driver, for example, when the user changes the network connection. In this case, the system will send a permission-to-close transition to each routine in the AppleTalk Transition Queue. This transition indicates that the system intends to close the .MPP driver, and in this way, each transition event handler routine in the queue has the opportunity to deny it permission to do so. When the system sends the permission-to-close transition, any routine in the AppleTalk Transition Queue that wishes to deny permission to close the .MPP driver can return a pointer to a Pascal string that gives the name of the application that placed the entry in the queue. If any routine denies permission to close the .MPP driver, the LAP Manager sends a cancel-close transition to every routine in the AppleTalk Transition Queue that previously received the permission-to-
close transition. The application that caused the system to send a permission-to-close transition application may display a dialog box informing the user that another application is using the .MPP driver and showing the name (if any) returned by the transition event handler routine. The dialog box gives the user the option of canceling the request to close AppleTalk or of closing AppleTalk anyway. If the user chooses to close AppleTalk despite the fact that an application is using it, the system calls the MPPClose function. The LAP Manager then sends a prepare-to-close transition to each application in the AppleTalk Transition Queue, informing each one that AppleTalk is about to close. In this case, your transition event handler routine must prepare for the imminent closing of AppleTalk; it cannot deny permission to the MPPClose function.
When the LAP Manager calls your transition event handler routine, the stack looks
like this:

Your routine can perform any tasks you wish to prepare for the imminent closing of AppleTalk, such as ending a session with a remote terminal and informing the user that the connection is being closed. You must return control to the LAP Manager as quickly as possible. Return 0 in the D0 register to indicate that your routine executed with no error.

Note
When the LAP Manager calls your routine with a prepare-to-close transition (that is, a routine selector of ATTransClose), you cannot prevent the .MPP driver from closing.

Permission-to-Close Transition

When a routine calls AppleTalk to inform AppleTalk that it wants to close the .MPP driver, the LAP Manager calls every transition event handler routine to request permission to close the .MPP driver with an ATTransClosePrep transition.

When the LAP Manager calls your transition event handler routine, the stack looks
like this:

The last parameter on the stack is a pointer to a 4-byte buffer. If you intend to deny the request to close the .MPP driver, you place in the buffer a pointer to a Pascal string containing the name of your application. This string belongs to the LAP Manager until the LAP Manager finishes processing the cancel-close transition. The routine that issued the request to close the .MPP driver can then display a dialog box telling the user the name of the application that is currently using AppleTalk.

Your routine can return either a function result of 0 in the D0 register, indicating that it accepts the request to close, or a 1 in the D0 register, indicating that it denies the request to close. Note that the operating system might elect to close the .MPP driver anyway; for example, if the user grants permission to close in response to a dialog box.

Because the LAP Manager calls your routine again (with the routine selector set to ATTransClose) before the .MPP driver actually closes, it is not necessary for your routine to do anything other than grant or deny permission in response to being called for a permission-to-close transition. However, you might want to prohibit users from opening new sessions or establishing new connections while you are waiting for the .MPP driver to close.

Note
Earlier versions of Inside Macintosh referred to the PATalkClosePrep function as a means of requesting permission to close the .MPP driver. The PATalkClosePrep function is now only used internally by the .MPP driver.

Cancel-Close Transition

When any routine in the AppleTalk Transition Queue denies permission for the .MPP driver to close, the LAP Manager calls each routine that has already received the permission-to-close transition with an ATTransCancelClose transition to inform it that the request to close the .MPP driver has been canceled.

When the LAP Manager calls your transition event handler routine, the stack looks
like this:

If your routine performed any tasks to prepare for the closing of AppleTalk, it
should reverse their effects when it is called with the routine selector set to ATTransCancelClose. Return 0 in the D0 register to indicate that your routine executed with no errors.

Network-Connection-Change Transition

To receive notification of network connection changes or transitions, your application should process ATTransNetworkTransition transitions. All applications running on an AppleTalk network should handle this event, but especially those applications that use multinode IDs.

For example, Apple Remote Access (ARA), which uses multinode architecture, allows
a user to establish a connection between two Macintosh computers over standard telephone lines. If the Macintosh that the user dials into is on an AppleTalk network, such as LocalTalk or EtherTalk, the Macintosh effectively becomes a node on that network, and all of the services on that network become available to the user. Because
of this relationship, any application that establishes an ARA connection needs to be notified when new AppleTalk connections are established or broken.

Note
Both the AppleTalk Session Protocol (ASP) and the AppleTalk Data Stream Protocol (ADSP) have been modified to respond to network-
connection-change transitions. When the AppleTalk drivers that implement these protocols receive notification of a network
disconnect transition, they close down sessions on the remote side
of the connection.
When the LAP Manager calls your transition event handler routine, the stack looks
like this:

Note
If you want to use the constant ATTransNetworkTransition for this transition event, you must first declare it in your application because it is not defined in the MPW interface files.
When the LAP Manager calls your routine, the last parameter on the stack contains a pointer to a record that contains a pointer to a network validation procedure. The process that sends notification of the network connection change uses this record to pass to the transition event handler routines a pointer to the network validation procedure; the transition event handler routines can then use this procedure to determine which networks are no longer connected, which networks remain connected, and which new networks have been added. To read the data in the record that this field points to, you must declare the following record type in your application:

TNetworkTransition = 
   RECORD
      private:          Ptr;     {pointer used internally by ARA}
      netValidProc:     ProcPtr; {pointer to the network }
                                 { validation procedure}
      newConnectivity:  Boolean; {TRUE = new connectivity, }
                                 { FALSE = loss of connectivity}
   END;
You cannot access a ProcPtr directly from Pascal. Therefore, if you write your application in Pascal and you want to handle the ATTransNetworkTransition
event, you need to include the following glue code so that you can access the
network validation procedure pointed to by the netValidProc field. Listing 10-5 shows the CallNetValidProc function glue code that you can use to call the netValidProc validation procedure passed in the TNetworkTransition record.

Listing 10-5 Glue code to handle the network-connection-change transition from Pascal

FUNCTION CallNetValidProc (netTrans: TNetworkTransitionPtr;
                         theNet: LongInt; p: ProcPtr): LongInt;
INLINE
$205F, { MOVEA.L  (SP)+,A0 ;get ProcPtr into A0, and make stack
                           ; right for call }
$4E90; { JSR      (A0)      ;call ProcPtr, and return to caller}
The code in Listing 10-6 demonstrates the calling sequence of events for the CallNetValidProc glue code.

Listing 10-6 Using the glue code for the network validation procedure

CASE selector OF
ATTransNetworkTransition:
BEGIN
   myTNetworkTransitionPtr := TNetworkTransitionPtr(p);
   if (myTNetworkTransitionPtr^.newConnectivity) THEN
   BEGIN 
   {
      /*Determine if there is a new connection.*/
   }
   END
      ELSE
   BEGIN
   {
      /*If there is a new connection, determine which network */
      /* address needs to be validated and assign the value to */
      /* checkThisNet.*/
   }
      checkThisNet = $1234FD00;  
                     /*network $1234, node $FD, socket not used*/
      if (CallNetValidProc(myTNetworkTransitionPtr, checkThisNet
      myTNetworkTransitionPtr^.netValidProc) <> 0) THEN

      /*Take the appropriate action depending on result.*/
Apple Remote Access (ARA) is an example of a process that generates network-
connection-change transitions to inform transition event handler routines and resident processes that network connectivity has changed. ARA uses the TNetworkTransition record to inform the routines about the changes. The newConnectivity field of the TNetworkTransition record identifies the type of change that has occurred:

Because ARA is connection oriented, it can identify the location of a specific network and inform transition event handler routines that a network is no longer reachable. You can use this information to identify the loss of connections immediately instead of waiting to discover that the other end of the connection is no longer responding.

The netValidProc field of the TNetWorkTransition record contains a network validation hook for a function that you can use to query ARA about a specific network to determine if that network is still reachable. If the network is reachable, the validation function returns TRUE. You can call this function repeatedly to determine the status of each network that you are interested in. If you use the Pascal language to write your transition event handler routine, you must implement glue code to use the network validation procedure.

The information that the validation function returns is valid only for those routines that use the function in response to a network-connection-change transition.

Note
A network-connection-change transition can be sent at interrupt time. Because of this, you should follow the conventions that apply when a routine is called during an interrupt. For example, your routine should not call routines that move memory and you should not call AppleTalk functions synchronously.

Flagship-Name-Change Transition

System 7 allows a user to enter a personalized name that identifies the system when
it is connected to an AppleTalk network. This is called the flagship name. An application that provides network services for a workstation should use the flagship name so
that the user can personalize the name that identifies the workstation to the network while reserving the use of the Chooser name for server connection identification.
If your application utilizes flagship names, your routine should process ATTransNameChangeTellTask transitions. When the LAP Manager calls your
routine with an ATTransNameChangeTellTask transition, you cannot prevent the flagship name from being changed.

When a routine calls the ATEvent procedure to change the flagship name, the LAP Manager calls every routine listed in the AppleTalk Transition Queue with an ATTransNameChangeTellTask transition. When the LAP Manager calls your transition event handler routine, the stack looks like this:

The last item on the stack is a pointer to a Pascal string that is the new flagship name to be registered. Your routine should remove the NBP registrations of entities under the old flagship name. You can make synchronous calls to NBP to remove a registered entity. Return a result of 0 in the D0 register to indicate that your routine executed with no error.

Note
Your application should only respond to flagship name changes
about which it receives notification. Do not attempt to change
the flagship name.

Permission-to-Change-Flagship-Name Transition

If your application utilizes flagship names, your transition event handler routine should process ATTransChangeNameAskTask transitions. When a process makes a request to change the flagship name, the LAP Manager calls every routine listed in the AppleTalk Transition Queue with an ATTransChangeNameAsk transition to request permission to change the name. When the LAP Manager calls your transition event handler routine, the stack looks like this:

The last item on the stack contains a pointer to a record that holds the new flagship name. The NameChangeInfo record also includes a field that you use to identify your application if you deny the name-change request. To read from and write to the record, you must declare the following record type in your application:

NameChangeInfo =  
   RECORD
      newObjStr:  Str32;      {new flagship name}
      name:       StringPtr;  {pointer to }
   END;                       { application's name}
The newObjStr field contains the proposed flagship name change. Your routine can inspect the newObjStr field. If your routine denies the name-change request, you
must provide as the value of the name field a pointer to a buffer containing a Pascal string that names your application. The LAP Manager returns this pointer to the process that requested the flagship name change so that the process can then display a dialog box telling the user the name of the application that refused the name change.

If your application does not deny the request, you can make synchronous calls to NBP to attempt to register your application under the new flagship name while your transaction event handler routine is processing the request. Apple Computer, Inc. recommends that you register your application with NBP under the new flagship name while you handle the ATTransChangeNameAskTask transition. However, you should not remove the old NBP registration until you are certain that other applications have not denied the request to change the flagship name. If another application denies the name-change request, the LAP Manager will send an ATTransCancelNameChange transition to cancel the name-
change request.

Return 0 in the D0 register to indicate that you accept the request to change the flagship name. To deny the request, return a nonzero number in the D0 register.

Cancel-Flagship-Name-Change Transition

When any routine in the AppleTalk Transition Queue refuses a request to change
the flagship name, the LAP Manager will send an ATTransCancelNameChange
transition to any transition event handler routines that acknowledged the ATTransNameChangeAskTask transition.

When the LAP Manager calls your transition event handler routine, the stack looks
like this:

If your routine registered any entities with NBP under the new flagship name while it processed the ATTransNameChangeAskTask, it should remove those entries now. You can make synchronous calls to NBP to remove registration of the entities.

Return a result of 0 in the D0 register to indicate that your routine executed with
no errors.

Cable-Range-Change Transition

A cable range is a range of network numbers beginning with the lowest network number and ending with the highest network number defined by a seed router for a network. All node addresses, including multinode addresses, that a system on a network acquires must have a network number within the defined cable range. (For information on multinodes, see the chapter "Multinode Architecture" in this book.)

Note
For nonextended networks, the lowest and the highest
numbers are the same.
When the cable range of a network changes because, for example, a router on the network shuts down, the LAP Manager will call your transition event handler routine with an ATTransCableChange transition. This transition notifies you that the cable range has changed for the network to which your node is connected.

Applications that use multinodes are examples of processes that should handle this transition. For multinode applications, after receiving notification of the cable range change, you should check the new cable range and determine if all the multinode IDs that the application acquired before the transition event occurred are still valid. If you discover multinode IDs that are no longer valid, you should call the RemoveNode function to remove them. Then you can call the AddNode function to obtain new multinode IDs that are within the valid cable range. See the chapter "Multinode Architecture" for information on RemoveNode and AddNode.

The LAP Manager sends you notice of a change in the cable range when the following events occur: AppleTalk first identifies the network router, the last router ages out, or AppleTalk first receives a Routing Table Maintenance Protocol (RTMP) broadcast packet that is different from the current range. The ATTransCableChange transition is implemented beginning with AppleTalk version 57. This transition event is issued at system task time only.

When the LAP Manager calls your transition event handler routine, the stack looks
like this:

The last item on the stack contains a pointer to a record that holds the new high and low cable numbers that identify the cable range. To access this information, you must declare a record of type TNewCRTrans. Here is the TNewCRTrans record type declaration:

TNewCRTrans =  
   RECORD
      newCableLo:    Integer; {new low cable in the range, }
                              { received from RTMP}
      newCableHigh:  Integer; {new high cable in the range, }
                              { received from RTMP}
   END;

CPU-Speed-Change Transition

Some applications change the CPU speed without rebooting the system. For example, an application may alter the cache states on the 68030 or 68040 CPUs or a third-party accelerator card may support dynamic speed changes made through a control panel 'cdev' file. Time-dependent processes need to be notified of changes to the CPU speed when these changes occur. If your application changes the CPU speed, you should use the ATEvent procedure to send notification of an ATTransSpeedChange transition to time-dependent processes. You must issue this transition event at system task time only. When you call the ATEvent procedure, pass ATTransSpeedChange as the value of the event parameter.

You must always notify LocalTalk when a CPU speed change occurs. LocalTalk includes a module that is time-dependent; the low-level timer values used in this code must be recalculated when the CPU speed changes. Altering the cache state on the 68030 does not affect LocalTalk, whereas altering the cache state on the 68040 does affect the LocalTalk timers. Therefore, an application that dynamically toggles caching on the 68040 should send notification of an ATTransSpeedChange transition. If the application does not do this and LocalTalk is the current network connection, the connection will be broken. LocalTalk implemented in AppleTalk version 57 or later recognizes the CPU-speed-
change transition event notification.

The transition event handler routine of any time-dependent process should handle the ATTransSpeedChange transition notification. When the LAP Manager calls your transition event handler routine, the stack looks like this:

Developer-Defined Transitions

Any AppleTalk transition event code that begins with an uppercase letter (that is, any value in the range $41 00 00 00 through $5A FF FF FF) indicates a developer-defined event. Because you cannot tell how the originator of such an event might interpret a nonzero function result, you must always return 0 in the D0 register for any AppleTalk transition event code that you do not recognize.

When you return a nonzero result code for certain developer-defined transitions, the LAP Manager may call your transition event handler routine a second time with a cancel transition analogous to the cancel-close transition.


[2] The constants marked with an asterisk are not included in the header files; you can use the routine selectors for these transitions, or you can define the constants in your application.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996