• No results found

Chapter 3 Management

4.5 Downline load algorithms

4.5.1 Downline load client

This section shows the Load Client algorithm.

In the case of a LAN load, the server address is normally not known. In that case, the first step is a Request Program message to the Load Assistance multicast address. These initial re-

quests are sent both in V4 and V3 format, unless the request is one that is defined only in MOP

V4. The first server that responds is used as the server for the rest of the load. However, if the load was initiated by a Boot message with Control = 1 (“Load server = Requesting system”), or if for some other reason the client knows which server should be used, then that server is used for the load and the multicast to the Load Assistance address is skipped.

The algorithm shows a timeout ofone minute on each transaction once the load is underway. The load client does not have to do retransmissions at that stage, since the load server does them, but it does need some sort of timeout to handle the case where the network is partitioned

or the load server has crashed. The load server does 15 retries at (by default) 4 second inter-

vals, so a one minute load client timeout is appropriate.

There are some special rules relating to the Secondary Loader. This fits in a single Memory Data message. A request for a Secondary Loader is answered with that data, not with an Assis-

tance Volunteer message. To ensure that subsequent load steps (for example Tertiary Loader

or Operating System) do not terminate prematurely due to receiving another copy of a secon-

dary loader, the load client ignores any Memory Data with Transfer Address messages that con-

tain load data whenever it is loading anything other than Secondary Loader. Similarly, the load client ignores any Memory Data with Transfer address messages that contain no data when it is loading a Secondary Loader. The load sequences for other program types terminate either with a Parameter Load message or with a Memory Load with Transfer Address message that contains no data.

The amount of memory data in each Memory Load message may vary; the client must not assume that it will receive a full size message each time. The memory data may be null, for example if the load server does not have the next segment of memory data available yet but wants to keep the client from timing out. In all cases, the client transfers the memory data in the message (if any) and responds with a request for the next higher sequence number.

PROCEDURE DLI.LoadClient (circ: POINTER TO Circuit; server: LANAddress; prog: ProgType; swid, scrid: SoftwareID)

RAISES {InsufficientResources, DataLinkError, Timeout} VAR op: POINTER TO Operation;

buff: POINTER TO Buffer;

msgtyp, seq, rseq, ldaddr: INTEGER; BEGIN

DLI.Alloc (op, buff); (* Allocate necessary resources, if available *) op^.CircPtr := circ; op^.Op := LoadClient; op^.Version := Unknown; op^.Address := server; op^.ProgramType := prog; IF prog = CMIPScript

THEN op^.Version := V4 (* CMIP Script is a V4 only function *) END;

TRY

IF op^.CircPtr^.DataLink IN LANTypes AND server = NullAddress

THEN (* LAN and server not selected yet *)

DLI.BuildReqProg (op, buff, prog, swid, scrid); buff^.Destination := LoadAssistance;

DLI.BackoffTransact (op, buff, buff);

op^.Address := buff^.Source; (* Whoever answers is our server *) IF prog = SecondaryLoader (* For Secondary the answer is the data *) THEN

IF buff^.Data[0] # MemLoadTA (* If it isn’t the right message type *) OR buff^.Length " 10 (* ...or message has null data *) THEN op^.Address := NullAddress; (* No server yet after all *)

« quietly ignore this message and keep requesting » END

ELSE (* for others, ask selected server again *) DLI.BuildReqProg (op, buff, prog, swid, scrid);

buff^.Destination := op^.Address; DLI.Transact (op, buff, buff); END

ELSE (* We know the server we want, talk to it *)

DLI.BuildReqProg (op, buff, prog, swid, scrid); buff^.Destination := op^.Address;

4.5.1: Downline load client

53

DLI.BackoffTransact (op, buff, buff); END

seq := 0; (* Start with sequence number zero *)

(* Note: on entry to the loop we have just received the first Memory Load message *) LOOP

msgtyp = buff^.Data[0];

IF msgtyp = MemLoadTA AND buff^.Length > 10 AND prog # SecondaryLoader THEN « quietly ignore this message »

END;

rseq := buff^.Data[1]; (* Get sequence number from received message *) IF rseq = seq (* If it matches the sequence number we want *) THEN

ldaddr := DLI.GetLong (buff, 2); (* Get memory address to load *) IF msgtyp = ParameterLoad

THEN « store the received parameters »

ELSEIF (msgtyp = MemLoad AND buff^.Length > 6) OR (msgtyp = MemLoadTA AND buff^.Length > 10) THEN

IF prog IN { Management, CMIPScript } AND ldaddr = 0 THEN « begin a new management file or CMIP script record » END;

« store data at specified ldaddr » END;

seq := (seq + 1) MOD 256; (* Look for the next consecutive sequence number *) IF msgtyp IN { MemLoadTA, ParameterLoad }

THEN

EXIT (* Leave the loop, done with the load *) END

END;

DLI.BuildReqLoad (buff, seq);

DLI.ReqResp (op, buff, buff, OneMinute, op^.Version); END;

IF msgtyp = ParameterLoad (* If system or diagnostic image load *) THEN

DLI.BuildReqLoad (buff, seq);

DLI.Send (op, buff, op^.Version); (*Send one more request to ACK the last message *) END;

FINALLY

DLI.Free (op, buff) END

END DLI.LoadClient;

The procedures below show how the Load protocol messages are constructed. Note that the Format Version byte (third byte)of the Request Program message should be set to reflect what protocol version is being sent; the V3 requests have the value 1 in Format Version, and the V4 requests have the value 4.

PROCEDURE DLI.BuildReqProg (op: POINTER TO Operation;

buff: POINTER TO Buffer; prog: ProgType; swid, scrid: SoftwareID); VAR idlen: INTEGER;

idstring: SoftwareID; BEGIN

buff^.Data[0] := RequestProgram;

buff^.Data[1] := « Device Type code of data link being used »; buff^.Data[2] := « Format Version, see above »;

IF prog = Diagnostic

THEN buff^.Data[3] := System

END;

IF prog = System THEN idstring := swid

ELSEIF prog = CMIPScript THEN idstring := scrid ELSE idstring := ""

END;

idlen := LENGTH (idstring); IF idlen > 0

THEN

buff^.Data[4] := idlen;

« store idstring starting at buff^.Data[5] » ELSEIF prog = System

THEN buff^.Data[4] := –1 (* Standard operating system *) ELSEIF prog = Diagnostic

THEN buff^.Data[4] := –2 (* Diagnostic system *) ELSE buff^.Data[4] := 0 (* No ID string *) END;

buff^.Data[5 + idlen] := 0 (* System processor *) (* Store TLV entry for Data Link Buffer Size *)

DLI.PutInteger (buff, 6 + idlen, 401); DLI.PutInteger (buff, 8 + idlen, 2);

DLI.PutInteger (buff, 10 + idlen, op^.CircPtr^.SDUSize); buff^.Length := 12 + idlen

END DLI.BuildReqProg;

PROCEDURE DLI.BuildReqLoad (buff: POINTER TO Buffer; seq: INTEGER); BEGIN

buff^.Data[0] := RequestLoad;

buff^.Data[1] := seq; (* Next sequence number we want *) buff^.Data[2] := 0; (* obsolete/reserved *)

buff^.Length := 3 END DLI.BuildReqLoad;