Important: The information in this document is obsolete and should not be used for new development.
Writing a User Routine for Connection Events
When you execute thedspInit
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
- ADSP has been informed by the remote connection end that the remote connection end is about to close the connection. An appropriate response might be to store a flag indicating that the connection end is about to close. When your application regains control, it can then display a dialog box informing the user of this event and asking whether the application should attempt to reconnect later.
- ADSP has determined that the remote connection end is not responding and so has closed the connection. Your user routine can attempt to open a new connection immediately. Alternatively, you can store a flag indicating that the connection has closed, and when your application regains control, it can display a dialog box asking the user whether to attempt to reconnect.
- ADSP has received an attention message from the remote connection end. Depending on what you are using the attention-message mechanism for, you might want to read the attention code in the
attnCode
field of the CCB and the attention message pointed to by theattnPtr
field of the CCB.- ADSP has received a forward reset command from the remote client end. It has then discarded all ADSP data not yet delivered, including the data in the receive queue of the local client end, and has resynchronized the connection. Your response to this event depends on the purpose for which you are using the forward reset mechanism. You might want to resend the last data you have sent or inform the user of the event.
userFlags
field of the CCB to determine what event caused the interrupt, and you can examine thestate
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 theuserFlags
field of the CCB.
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
- 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 theuserFlags
field.
and then clears the bit in theuserFlags
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 theflag
bit. The definitions of proceduresPushA5
,GetMyTRCCBA5
, andPopA5
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;