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 5 - AppleTalk Data Stream Protocol (ADSP) / Using ADSP


Writing a User Routine for Connection Events

When you execute the dspInit routine, you can specify a pointer to a routine that you provide (referred to as the user routine). Whenever an unsolicited connection event occurs, ADSP sets a flag in the CCB and calls the user routine. The user routine must clear the flag to acknowledge that it has read the flag field, and then it can respond to the event in any manner you deem appropriate. The CCB flags are described in"The ADSP Connection Control Block Record" beginning on page 5-35. The four following types
of unsolicited connection events set flags in the CCB:

When ADSP calls your user routine, the CPU is in interrupt-processing mode and register A1 contains a pointer to the CCB of the connection end that generated the event. You can examine the userFlags field of the CCB to determine what event caused the interrupt, and you can examine the state field of the CCB to determine the current state of the connection.

Because the CPU is set to interrupt-processing mode, your user routine must preserve
all registers other than A0, A1, D0, D1, and D2. Your routine must not make any direct
or indirect calls to the Memory Manager, and it cannot depend on handles to unlocked blocks being valid. If you want to use any of your application's global variables, you must save the contents of the A5 register before using the variables, and you must restore the A5 register before your routine terminates. Listing 5-1 and Listing 5-3 illustrate the use of the CCB to store the pointer to your application's global variables.

If you want to execute a routine each time an unsolicited connection event occurs but the interrupt environment is too restrictive, you can specify a NIL pointer to the user routine and periodically poll the userFlags field of the CCB.

WARNING
When an unsolicited connection event occurs, you must clear the bit in the userFlags field by setting it to 0 or the connection will hang. To ensure that you do not lose any attention messages, you must read any attention messages into an internal buffer before you clear the bit in the userFlags field.
Listing 5-3 on page 5-28 shows the user routine called by Listing 5-1 on page 5-17. When this routine is called, it first checks the CCB to determine the source of the interrupt
and then clears the bit in the userFlags field of the CCB. If the routine has received
an attention message, the user routine reads the message into an internal buffer before
it clears the flag bit. The definitions of procedures PushA5, GetMyTRCCBA5, and
PopA5 are shown in Listing 5-3 for your convenience. In a complete application these procedures would be defined in the calling routine (see Listing 5-1 for an example).

Listing 5-3 An ADSP user routine

PROCEDURE PushA5;          {moves current value of A5 onto stack}
   INLINE $2F0D;           {MOVE.L A5,-(SP)}

PROCEDURE GetMyTRCCBA5;    {retrieves A5 from the head of the TRCCB }
                           { (pointed to by A1) and puts it in A5 register}
   INLINE $2A69, $FFFC;    {MOVE.L -4(A1), A5}

PROCEDURE PopA5;           {restores A5 from stack}
   INLINE $2A5F;           {MOVE.L (SP)+, A5}

PROCEDURE MyConnectionEvtUserRoutine;

BEGIN
{The connection received an unexpected connection event. Find }
{ out what kind and process accordingly.}
   
   PushA5;                 {save the current A5}
   GetMyTRCCBA5;           {set up A5 to point to your }
                           { application's global variables}
   
   WITH dspCCB.u DO
   BEGIN
      IF BAND(userFlags, eClosed) <> 0 THEN TellUserItsClosed;
      IF BAND(userFlags, eTearDown) <> 0 THEN TellUserItsBroken;
      IF BAND(userFlags, eFwdReset) <> 0 THEN TellUserItsReset;
      IF BAND(userFlags, eAttention) <> 0 THEN
      BEGIN                {the event is an attention message}
         myAttnCode := AttnCode;       
                           {get the attention code}
         CopyAttnMsg(AttnPtr, AttnSize, @myAttnData);
                           {copy the attention message into your buffer}
         tempFlag := userFlags;
         tempCFlag := eAttention;
         BClr(LongInt(tempFlag), tempCFlag);
                           {clear the flag}
         userFlags := tempFlag;
         {Do something with the message.}
      END;
      gReceivedAnEvent := TRUE
   END;
   PopA5                   {restore the current A5}
END;

Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996