Important: The information in this document is obsolete and should not be used for new development.
Receiving Packets Addressed to Your Multinode
Your application must provide a routine that receives packets addressed to the multinode and broadcast packets. Because the .MPP driver passes values to your multinode receive routine in registers when it calls the routine, you must code the receive routine in assembly language.You pass the address of your receive routine to the .MPP driver when you call the
AddNode
routine to open a multinode. The .MPP driver internally associates your receive routine with the multinode address that it assigns, and it calls your receive routine to handle a packet addressed to the multinode or a broadcast packet.If your application acquires more than one multinode, you can use the same receive routine for each of these multinodes. If you use the same receive routine to receive and process packets for more than one multinode, the .MPP driver will call that receive routine only once for each broadcast packet that it receives.
A multinode receive routine is similar in concept to a socket listener that receives packets addressed to a specific socket. The chapter "Datagram Delivery Protocol (DDP)" in
this book includes a sample socket listener. To create a receive routine, perform the following steps:
- Allocate a buffer to hold the data that you expect to receive.
- The maximum amount of data in a DDP packet is 586 bytes. All packets addressed to multinodes use a long header, which is 13 bytes long. If your receive routine places the packet header as well as the data portion in the buffer, make the buffer large enough to hold both parts of the packet contents.
- If you use the same receive routine to receive and process packets for more than one multinode, you should provide a separate buffer to store the data for each multinode. You can define a single buffer for each multinode to hold the contents of both the header and data portions of a packet, or you can define a pair of buffers for each multinode to separate the packet's contents.
- Determine the number of bytes that have already been read into the .MPP driver's internal buffer, called the RHA.
- To do this, subtract the beginning address of the read-header area (RHA) from the value in register A3, which points past the last byte read into the RHA. To locate the offset at the beginning of the RHA, you can use the
toRHA
equate.When a frame that contains either a DDP packet that is addressed to your multinode or a broadcast packet is delivered to the node that is running your multinode applica-
tion, the node's CPU is interrupted and the .MPP driver's interrupt handler gets control to service the interrupt. As the frame's first 3 bytes are read into a FIFO buffer, the .MPP driver's interrupt handler moves these bytes into the RHA.
- Use the
ReadPacket
andReadRest
routines to read the rest of the incoming data that constitutes the packet.How you handle a packet after you read it is particular to your application. For example, if your application implements NBP, you can check the packet's entity name object and type fields against entries in your names table to determine whether to process the packet and respond to the sender. If you respond, the packet you send must adhere to the structure of a standard AppleTalk packet. (See Inside AppleTalk, second edition, for the AppleTalk packet structure.) For a brief description of how ARA uses multinode, see the discussion on page 12-5.
- You can call the
ReadPacket
routine as many times as you like to read the data piece by piece into one or more data buffers that you have defined, but you must always use theReadRest
routine to read the final piece of the data packet. TheReadRest
routine restores the machine state (the stack pointers, status register, and so forth) and checks for error conditions.- Before you call the
ReadPacket
routine, you must place a pointer to the data buffer for which you allocated memory in the A3 register. You must also place the number of bytes you want to read in the D3 register. You must not request more bytes than remain in the data packet.- After you have called the
ReadRest
routine, you can use registers A0 through A3 and D0 through D3 for your own use, but you must preserve all other registers. You cannot depend on having access to your application's global variables.
- Calling
ReadPacket
andReadRest
when LocalTalk is the data link- If LocalTalk is the data link that is being used, your receive routine
has less than 95 microseconds (best case) to read more data with aReadPacket
orReadRest
routine. If you need more time, you
can read another 3 bytes into the RHA, which will allow you an
additional 95 microseconds. Note that the RHA may only have 8 bytes still available.
- If the packet header contains a checksum, you can calculate a checksum for both the header and data portions of the packet and then verify the sum of these two values against the value in the
checksum
field of the packet header. If the checksum you calculate does not match the one in the header, the data has been corrupted in
some way. (Figure 12-1 on page 12-5 shows the DDP packet header, including the checksum field.)The chapter "Datagram Delivery Protocol (DDP)" in this book contains a sample checksum routine to be used for a socket listener; this routine is equally applicable to a multinode receive routine.
Calling ReadPacket to Read in the Packet Contents
To call theReadPacket
routine, execute a JSR instruction to the address in the A4 register. TheReadPacket
routine uses the registers as follows:
Registers on entry to the ReadPacket
routineA3 Pointer to a buffer to hold the data you want to read D3 Size in of bytes to be read; must be nonzero
Registers on exit from the ReadPacket
routineA0 Unchanged A1 Unchanged A2 Unchanged A3 Pointer to the first byte after the last byte read into buffer A4 Unchanged D0 Changed D1 Number of bytes left to be read D2 Unchanged D3 Equals 0 if the requested number of bytes were read, nonzero if error After every time that you call
ReadPacket
, you must check the zero (z
) flag in the status register for errors because theReadPacket
routine indicates an error by clearing it to 0. If theReadPacket
routine returns an error, you must terminate execution of your receive routine with an RTS instruction without callingReadPacket
again or callingReadRest
at all.Calling ReadRest to Complete Reading in the Packet Contents
Call theReadRest
routine to read the last portion of the data packet, or call it after
you have read all the data withReadPacket
routines and before you do any other processing or terminate execution. After you callReadRest
, you must check the zero (z
) flag in the status register for errors.After you call the
ReadRest
routine, you must terminate execution of your receive routine with an RTS instruction whether or not theReadRest
routine returns an error.When you call the
ReadRest
routine, you must provide in the A3 register a pointer to
a data buffer and you must indicate in the D3 register the size of the data buffer. If
you have already read all of the data using theReadPacket
routine, specify a buffer
of size 0.
To call the
- WARNING
- If you do not call the
ReadRest
routine after the last time you call theReadPacket
routine successfully, the system will crash.ReadRest
routine, execute a JSR instruction to an address 2 bytes past the address in the A4 register:
JSR 2(A4)TheReadRest
routine uses the registers as follows:
Registers on entry to the ReadRest
routineA3 Pointer to a buffer to hold the data you want to read D3 Size of the buffer (word length); may be 0
Registers on exit from the ReadRest
routineA0 Unchanged A1 Unchanged A2 Unchanged A3 Pointer to first byte after the last byte read into buffer D0 Changed D1 Changed: number of bytes left to be read D2 Unchanged D3 Equals 0 if the requested number of bytes were read, is less than 0 if the
packet data was too large to fit in the buffer and the data was truncated, and
is greater than 0 to indicate the number of bytes that were not readFor more information on how your receive routine can use the registers, see the discussion of the socket listener routine in the chapter "Datagram Delivery Protocol (DDP)" in this book.