{$X+,V-,B-}
program S_PEP;

{ Testprogram for the nwPEP unit / NwTP 0.6 API. (c) 1993,1995, R.Spronk }

uses crt,nwMisc,nwIPX,nwPEP; { Listener/ Slave }

{ Listen for incoming packet.. sent acknowledgement of receipt }

{ Note that the acknowledgement is done automatically by the receiving ESR }

CONST IOSocket=$5678;

Var ListenECB    :Tecb;
    ListenPepHdr     :TpepHeader;

    SendECB       :Tecb;
    SendPepHdr    :TpepHeader;

    socket        :word;
    buf           :array[1..546] of byte;
    t             :byte;
    ReceivedBufLen:word;
    PacketReceived:boolean;

    NewStack:array[1..1024] of word;  { !! used by ESR }
    StackBottom:word;                 { !! used by ESR }



{$F+}
Procedure ListenAndAckHandler(Var p:TPecb);
begin
If (ListenECB.CompletionCode<>0)        
 or (ListenPepHdr.IPXhdr.packetType<>PEP_PACKET_TYPE) 
 or (ListenPepHdr.clienttype<>$EA)
  then IPXlistenForPacket(ListenECB)
  else begin
       PacketReceived:=true;
       ListenPepHdr.IPXhdr.source.socket:=swap(ListenPepHdr.IPXhdr.source.socket);
       { socket is hi-lo in IPX/PEPHeaders. SetupSendECB expects lo-hi }
       PEPsetupSendECB(NIL,IOsocket,ListenPepHdr.IPXhdr.source,@buf,0,
                       SendPepHdr,SendECB);
       SendPepHdr.TransactionId:=ListenPepHdr.TransactionId;
       SendPepHdr.clientType:=$EA;
       IPXsendPacket(SendECB);
       end;
end;
{$F-}

{$F+}
Procedure ListenAndAckESR; assembler;
asm { ES:SI are the only valid registers when entering this procedure ! }
    mov dx, seg stackbottom
    mov ds, dx

    mov dx,ss  { setup of a new local stack }
    mov bx,sp  { ss:sp copied to dx:bx}
    mov ax,ds
    mov ss,ax
    mov sp,offset stackbottom
    push dx    { push old ss:sp on new stack }
    push bx

    push es    { push es:si on stack as local vars }
    push si
    mov  di,sp

    push ss    { push address of local ptr on stack }
    push di
    CALL ListenAndAckHandler

    add sp,4   { skip stack ptr-copy }
    pop bx     { restore ss:sp from new stack }
    pop dx
    mov sp,bx
    mov ss,dx
end;
{$F-}


Var dest:TinternetworkAddress;
    ticks,ticks2:word;

begin
IF NOT IpxInitialize
 then begin
      writeln('Ipx needs to be installed.');
      halt(1);
      end;
socket:=IOSocket;
IF NOT IPXopenSocket(Socket,SHORT_LIVED_SOCKET)
 then begin
      writeln('IPXopenSocket returned error# ',nwIPX.result);
      halt(1);
      end;

{ listen for incoming pep-packet }

PacketReceived:=False;
{ Empty receive buffer (ListenECB.fragment[2].address^) }
FillChar(buf,546,#0);

{ Setup ECB and IPX header }
PEPSetupListenECB(Addr(ListenAndAckESR),IOsocket,@buf,546,
                  ListenPepHdr,ListenECB);

IPXListenForPacket(ListenECB);
writeln('Listening for incoming packet.');

IPXGetIntervalMarker(ticks);
REPEAT
 IPXrelinquishControl;
 IPXGetIntervalMarker(ticks2)
UNTIL PacketReceived or ((ticks2-ticks)>(30*18));

{ do something with received buffer }
IF PacketReceived
 then writeln('Packet received and acknowledged.')
 else writeln('Timeout: no packet received in 30 seconds.');

IF NOT IPXcloseSocket(IOsocket)
 then writeln('IPXcloseSocket returned error# ',nwIPX.result);

end.
