-- 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..