• No results found

Downline load server listener

Chapter 3 Management

4.5 Downline load algorithms

4.5.2 Downline load server

4.5.2.1 Downline load server listener

This section shows the operation of the load server listener. It listens for load requests initi-

ated by load clients, and uses the Request Program message and information in the Client data-

base to decide whether and how to process the request. This process is active only if Load serv-

ice is enabled for the circuit. The outline of the algorithm is as follows:

• Aclient database lookup is performed first.

- First look for a client entry by circuit and (if a LAN) data link address.

- If no match is found and this is a LAN, look for a client entry by circuit and de-

vice type.

• IfKnown Clients Only is False, and a syntactically valid Software ID string was included

in the request, then the load can proceed whether or not an entry is found in the client lookup. Otherwise, if no entry is found, this is an Unrecognized Client.

If an entry is found, the file names it specifies are used as the load files for this load

4.5.2.1: Downline load server listener

55

• If the request specified a Software ID string, map the ID string to a file name and see if that file exists. If not, this is a File Open Error if a client entry was found previously, and an Unrecognized Client otherwise. (Note that the Software ID string overrides cli-

ent database load file information.)

• If this is a LAN and the original request was addressed to the Load Assistance multicast address, send an Assistance Volunteer message and wait for a directed Re-

quest Program message (indicating this node was selected). If none is received, quietly go back to listening for other requests. (This condition is not an error and no event should be logged in this case.)

Note: as shown here the Assistance Volunteer is sent before any files are opened, except where Software ID strings are involved. An implementation may instead open files

first, and not volunteer until it has sucessfully done the open. This will avoid volunteer-

ing when the client database points to non-existent or inaccessible files.

The secondary loader is a special case: the entire secondary loader is sent in a single message. NoAssistance Volunteer is sent in this case; the response to the Request Pro-

gram message is simply a message containing the secondary loader.

• Load the client according to the received request, with load file as determined above. PROCEDURE DLI.LoadServer (circ: POINTER TO Circuit);

VAR op: POINTER TO Operation; buff: POINTER TO Buffer; device: DevType;

prog: ProgType; idstring: SoftwareID;

loadok: Boolean; (* True if we can load this client *) i: INTEGER;

EXCEPTION Quit; BEGIN

NEW (op); (* Get an Operation record *)

op^.CircPtr := circ; op^.Op := LoadServer; LOOP

TRY

op^.Address := NullAddress; (* We’ll listen to any remote station address *) op^.Version := Unknown; (* Accept any version *)

DLI.Receive (op, buff, Infinite); (* Wait for a message, however long it takes *) IF buff^.Data[1] = 31 (* Special case *)

THEN

device := 37 (* 37 is LQA, 31 is alternate code for LQA *) ELSE

device := buff^.Data[1] (* Get requester’s device type *) END

IF buff^.Length < 3

THEN prog := SecondaryLoader (* Default if no program type in message *) ELSE prog := buff^.Data[3]; (* Get program type *)

IF prog = System THEN

IF « Request Program message indicates request for Diagnostic Image » THEN prog := Diagnostic

END END END;

op^.ProgramType := prog;

IF NOT DLI.ValidID (idstring)

THEN idstring := "" (* If supplied ID isn’t valid, pretend none was supplied *) END;

IF « Data Link Buffer Size present in message »

THEN op^.SDUSize := « Data Link Buffer Size from message » ELSE op^.SDUSize := 262

END;

loadok := FALSE;

op^.Client := DLI.FindClientByCircAddr (circ, buff^.Source); IF circ^.DataLink IN LANTypes AND op^.Client = NIL THEN

op^.Client := DLI.FindClientByCircDev (circ, device) END; IF op^.Client # NIL THEN loadok := TRUE; op^.SecondaryLoader := op^.Client^.SecondaryLoader; op^.TertiaryLoader := op^.Client^.TertiaryLoader; op^.SystemImage := op^.Client^.SystemImage; op^.DiagnosticImage := op^.Client^.DiagnosticImage; op^.ManagementImage := op^.Client^.ManagementImage; op^.ScriptFile := op^.Client^.ScriptFile; IF idstring # ""

THEN (* ID string supplied, override database filename *) loadok := DLI.MapIDString (op, idstring)

END

ELSEIF NOT KnownClientsOnly (* No client entry found *) IF idstring # ""

THEN (* ID string supplied, map to filename *) loadok := DLI.MapIDString (op, idstring)

END END; IF loadok THEN

IF circ^.DataLink IN LANTypes

AND buff^.Destination[0] = 1 (* multicast request requires volunteer response *) AND op^.ProgramType # SecondaryLoader (* except secondary loaders *) THEN

FOR i := 1 TO RetransmitMax DO

LAN.SendVolunteer (op, buff); (* Volunteer to serve *) TRY

DLI.Receive (op, buff, OneMinute); EXCEPT

| Timeout: RAISE (Quit) END;

« received Request Program message should be the same as the multicast request that initiated the lookup. If not, quit and report a Load Request Failed event, Reason = Protocol Error. »

IF buff^.Destination[0] = 0

THEN EXIT (* Request Program direct to us, carry on *) ELSEIF i = RetransmitMax

THEN RAISE (Quit) (* Volunteer isn’t being heard, quit *) END

END END;

DLI.PerformLoad (op,buff); (* Go perform the actual load with these parameters *) « report a Load Request Completed event »

4.5.2.2: Downline load data transfer phase

57

ELSE

IF op^.Client = NIL

THEN (* Couldn’t load because no matching client entry *) « report an Unrecognized Load Client event »

ELSE (* Couldn’t load because of bad Software ID *) « report a Load Request Failed event, reason = File Open Error » END

EXCEPT

| Quit: (* Quit load attempt quietly *)

| ELSE « report a Load Request Failed event, Reason as indicated by the exception » END;

DLI.ReceiveDone (buff) END

END DLI.LoadServer;

PROCEDURE DLI.MapIDString (op: POINTER TO Operation; idstring: SoftwareID) : Boolean VAR filename: FileSpec;

exists: Boolean; BEGIN

filename := « map idstring to file name »; CASE op^.ProgramType OF

SecondaryLoader: op^.SecondaryLoader := filename | TertiaryLoader: op^.TertiaryLoader := filename |

System: op^.SystemImage := filename |

Diagnostic: op^.DiagnosticImage := filename |

Management: op^.ManagementImage := filename |

ScriptFile: op^.ScriptFile := filename

END;

exists := « True if file named by filename exists »; RETURN (exists)

END DLI.MapIDString;

PROCEDURE LAN.SendVolunteer (op: POINTER TO Operation, buff: POINTER TO Buffer); BEGIN

buff^.Destination := op^.Address; buff^.Length := 1;

buff^.Data[0] := AssistanceVolunteer; DLI.Send (op, buff, op^.Version) END LAN.SendVolunteer;