-- File: PhoneAdoptionPup.mesa - last edit:
-- AOF 4-Feb-88 19:38:14
-- HGM 26-Oct-85 23:21:47
-- LSK 28-Jun-85 14:56:18
-- Copyright (C) 1984, 1985, 1988 by Xerox Corporation. All rights reserved.
DIRECTORY
Buffer USING [Buffer, Type],
CommHeap USING [zone],
CommUtil USING [GetEthernetHostNumber],
Driver USING [Device],
Environment USING [bytesPerWord],
Inline USING [LongCOPY],
Mopcodes USING [zADD, zAND, zLI1, zLINB],
NSBuffer USING [Body],
PhoneAdoption USING [AdoptForNS],
PhoneCreate USING [],
PhoneNet USING [Initialize, Unsupported],
Protocol1 USING [
AddFamilyMember, Family,
MatrixRecord, DecapsulatorProc, EncapsulatorProc],
PupDefs USING [PupPackageMake],
PupTypes USING [],
PupRouterDefs USING [ContextObject],
RS232C USING [ChannelHandle, CommParamObject, Create],
RS232CEnvironment USING [],
SptpOps USING [GetDevice, defaultMaxRS232CBytes, GetVersion],
SptpProtocol USING [Encapsulation, EncapsulationObject, ProtocolVersion],
System USING [NetworkNumber];
PhoneAdoptionPup: MONITOR
IMPORTS
CommHeap, CommUtil, Inline, PhoneAdoption, PhoneNet,
SptpOps, Protocol1, PupDefs, RS232C
EXPORTS Buffer, PhoneCreate =
BEGIN
bpw: NATURAL = Environment.bytesPerWord;
Device: PUBLIC <<Buffer>> TYPE = Driver.Device;
CreateSimplePhoneNet: PUBLIC PROC [
lineNumber: CARDINAL, pupNet: CARDINAL, nsNet: System.NetworkNumber] =
BEGIN
parms: RS232C.CommParamObject ← [
full, bitSynchronous, bps9600, directConn[]];
chan: RS232C.ChannelHandle ← RS232C.Create[
lineNumber, @parms, preemptAlways, preemptNever];
PhoneNet.Initialize [
lineNumber: lineNumber, channel: chan, commParams: @parms,
negotiationMode: active, hardwareStatsAvailable: TRUE,
ourEntityClass: internetworkRouter];
PhoneAdoption.AdoptForNS [lineNumber<<, FALSE, System.nullNetworkNumber>>];
AdoptForPup[lineNumber, pupNet];
END; --CreateSimplePhoneNet
AdoptForPup: PROC [lineNumber: CARDINAL, pupNetNumber: CARDINAL] =
BEGIN
pupHostNumber: CARDINAL = CommUtil.GetEthernetHostNumber[];
driver: Device = SptpOps.GetDevice[lineNumber];
family: Protocol1.Family ← PupDefs.PupPackageMake[];
matrix: Protocol1.MatrixRecord ← [ --AddFamilyMember copies fields
family: family, context: ,
encapsulator: EncapsulatePupPhonenet,
decapsulator: DecapsulatePupPhonenet];
matrix.context ← CommHeap.zone.NEW[PupRouterDefs.ContextObject ← [
protocol: NIL, network: driver,
pupNetNumber: pupNetNumber, pupHostNumber: pupHostNumber]];
Protocol1.AddFamilyMember[driver, @matrix];
matrix.family.stateChanged[driver, matrix.context, add];
END;
--**************** Encapsulation and decapsulation **************
DecapsulatePupPhonenet: Protocol1.DecapsulatorProc =
--PROCEDURE [b: Buffer.Buffer] RETURNS [type: Buffer.Type]
BEGIN
<<
When coming in here we are assured that b.linkLayer.blockPointer
points to the beginning of the physical frame. That frame starts with
the sptp's encapsulation record. From that information we should be
able to compute the address of the data portion.
These calls to SptpOps.Get* are expensive. It would be nice to be able
to get to some state object more cheaply to determine whether we are
connected to an SIU or not.
>>
size: NATURAL;
body: NSBuffer.Body;
device: Device = b.fo.network; --get pointer to network
<<version: SptpProtocol.ProtocolVersion = SptpOps.GetVersion[device];>>
WITH e: LOOPHOLE[b.linkLayer.blockPointer, SptpProtocol.Encapsulation]
SELECT FROM pup => size ← SIZE[pup SptpProtocol.EncapsulationObject];
ENDCASE => RETURN[vagrant]; --go away
body ← LOOPHOLE[b.linkLayer.blockPointer + size]; --that's fair
b.highLayer ← [LOOPHOLE[body], 0, body.pktLength]; --from the packet
b.linkLayer.stopIndexPlusOne ← (bpw * size); --'size' now bytes
RETURN[pup]; --that was easy
END;
EncapsulatePupPhonenet: Protocol1.EncapsulatorProc =
BEGIN
<<
Coming in here we know that the packet is an NS packet and that
b.highLayer.blockPointer points to the NSBuffer.BodyBody. We need to back
off some number of bytes from that point and stick in the proper encap-
sulation.
NB: The Inline.LongCOPYs are here because the compiler generates somewhat
unuseful code if you use a more direct approach to things. It first blaps
in a non-descriminated record which is several bytes longer than an
ns SptpProtocol.EncapsulationObject. Then it goes back and fills in the
particulars. Regettably by then the first 'n' bytes of the original
packet are destroyed.
>>
size: NATURAL; --this variable is overloaded
link: LONG POINTER; --computed to point to data link fields
encapsulation: SptpProtocol.EncapsulationObject; --this is our local copy
device: Device = b.fo.network; --get pointer to network
body: NSBuffer.Body = LOOPHOLE[b.highLayer.blockPointer];
of: NATURAL = body.pktLength / SptpOps.defaultMaxRS232CBytes;
version: SptpProtocol.ProtocolVersion = SptpOps.GetVersion[device];
SELECT version FROM
version4 =>
BEGIN
encapsulation ← [pup[LTA: FALSE, more: (of # 0), fragment: [0, of]]];
size ← SIZE[pup SptpProtocol.EncapsulationObject];
END;
version3 =>
BEGIN
IF (of # 0) THEN ERROR PhoneNet.Unsupported;
encapsulation ← [pup[LTA: FALSE, more: FALSE, fragment: [0, 0]]];
size ← SIZE[pup SptpProtocol.EncapsulationObject];
END;
ENDCASE => ERROR PhoneNet.Unsupported;
link ← body - size; --this is backoff to beginning of link layer
Inline.LongCOPY[to: link, from: @encapsulation, nwords: size];
size ← bpw * size; -- now represents data link size in bytes
b.linkLayer ← [link, 0, size]; --set the link layer values
b.fo.driver.length ← Roundup[body.pktLength] + size; --frame is sum of both
END; --EncapsulatePupPhonenet
Roundup: PROC[NATURAL] RETURNS[NATURAL] = MACHINE CODE {
Mopcodes.zLI1; Mopcodes.zADD; Mopcodes.zLINB, 376B; Mopcodes.zAND};
minBytesPerPup: CARDINAL = 22;
END..