-- TranslationServer.mesa
-- HGM, March 16, 1981  1:24 PM

-- Provide a Pup address for machines that have a 48 bit host number.

DIRECTORY
  BufferDefs USING [BufferAccessHandle, OisBuffer],
  NameServerDefs USING [OISCPNameServer],
  Router USING [FindMyHostID, XmitStatus],
  Socket USING [
    Abort, ChannelAborted, ChannelHandle, Create, defaultWaitTime, Delete,
    GetPacket, SetWaitTime, TimeOut],
  SocketInternal USING [GetBufferPool, SocketHandle],
  System USING [],
  OISCP USING [ReturnFreeOisBuffer, unknownNetID],
  OISCPConstantsAdditions USING [pupAddressTranslation],
  SpecialSystem USING [NetworkAddress, SocketNumber];

TranslationServer: PROGRAM
  IMPORTS
    OISCP, Router, Socket, SocketInternal, NameServerDefs
  EXPORTS System, Socket
  SHARES BufferDefs =
  BEGIN

  -- Krock to make TYPEs work ok
  ChannelHandle: PUBLIC TYPE = SocketInternal.SocketHandle;
  NetworkAddress: PUBLIC TYPE = SpecialSystem.NetworkAddress;

  -- These should move to OISCPTypes
  translationRequest: CARDINAL = 1;
  translationResponse: CARDINAL = 2;
  translationError: CARDINAL = 3;

  cH: Socket.ChannelHandle;
  localAddr: NetworkAddress;
  translationFork: PROCESS;

  CreateServer: PUBLIC PROCEDURE =
    BEGIN
    localAddr ←
      [net: OISCP.unknownNetID, host: Router.FindMyHostID[],
	socket: OISCPConstantsAdditions.pupAddressTranslation];
    cH ← Socket.Create[localAddr, 0, 2, 0, FALSE];
    translationFork ← FORK TranslationServer[];
    END;

  DeleteServer: PUBLIC PROCEDURE =
    BEGIN Socket.Abort[cH]; JOIN translationFork; Socket.Delete[cH]; END;

  TranslationServer: PROCEDURE =
    BEGIN
    b: BufferDefs.OisBuffer;
    pool: BufferDefs.BufferAccessHandle ← SocketInternal.GetBufferPool[cH];
    Socket.SetWaitTime[cH, Socket.defaultWaitTime];
    DO
      b ← NIL;
      b ← Socket.GetPacket[
	cH ! Socket.TimeOut => RETRY; Socket.ChannelAborted => GOTO GoAway];
      SELECT LOOPHOLE[b.status, Router.XmitStatus] FROM
	goodCompletion =>
	  BEGIN
	  IF b.ois.oisWords[2] = translationRequest THEN
	    BEGIN
	    NameServerDefs.OISCPNameServer[cH, b];
	    LOOP;
	    END;
	  END;
	ENDCASE;
      OISCP.ReturnFreeOisBuffer[b];
      REPEAT GoAway => NULL;
      ENDLOOP;
    END;

  CreateServer[];
  END.