{$X+,V-,B-} program S1_PEP; { Listening Process / receiver / Slave } { Testprogram for the nwPEP unit / NwTP 0.6 API. (c) 1993,1995, R.Spronk } uses crt,nwMisc,nwIPX,nwPEP; Var ListenECB :Tecb; { used to listen for packets } ListenPepHdr :TpepHeader; SendECB :Tecb; { used to send acknowledgements } SendPepHdr :TpepHeader; IOsocket :word; DataBuffer :array[1..546] of byte; SendDataBuffer:byte; PacketReceived :Boolean; LastTransactionID:LongInt; BytesReceived :Word; NewStack:array[1..8192] of word; { !! used by ESR } StackBottom:word; { !! used by ESR } lnr:word; Procedure CheckError(err:boolean; errNbr:word); begin if err then begin CASE errNbr of $0100:writeln('IPX needs to be installed.'); $0101:writeln('ERROR: Connection not established. A Timeout occured'); $0102:writeln('ERROR: The transfer is aborted; A timeout occured.'); $10FE:writeln('Error opening socket: Socket Table Is Full.'); $10FF:writeln('Error opening socket: Socket is already open.'); else writeln('Unspecified error.'); end; {case} IPXcloseSocket(IOsocket); halt(1); end; end; Function TimeOut(t1,t2:word;n:byte):boolean; { ticks t2 - ticks t1 > n seconds ? } Var lt1,lt2:LongInt; begin lt2:=t2; if t1>t2 then lt2:=lt2+$FFFF; TimeOut:=(lt2-t1)>(n*18); end; {$F+} Procedure ListenAndAckHandler; begin lnr:=ListenPepHdr.TransactionID; If (ListenECB.CompletionCode<>0) or (ListenPepHdr.IPXhdr.packetType<>PEP_PACKET_TYPE) or (ListenPepHdr.clienttype<>$EA) or (ListenPepHdr.TransactionIDLastTransactionID); { new packet received } { Acknowledge new packets and duplicates of the latest packet, } { as the original acknowledgement may have been lost. } BytesReceived:=swap(ListenPepHdr.IPXhdr.length)-SizeOf(TpepHeader); LastTransactionID:=ListenPepHdr.TransactionID; { Setup acknowledgement ECB and PEPheader, and send it. } if 1=1 {SendECB.InUseFlag=0} then begin 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,@SendDataBuffer,0, SendPepHdr,SendECB); SendPepHdr.TransactionId:=LastTransactionID; SendPepHdr.ClientType:=$EA; IPXsendPacket(SendECB); end; end; end; {$F-} {$F+} Procedure ListenAndAckESR; assembler; asm 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 CALL ListenAndAckHandler pop bx { restore ss:sp from new stack } pop dx mov sp,bx mov ss,dx end; {$F-} Var ticks,ticks2 :word; FileName:string; FileSize:LongInt; begin lnr:=0; IpxInitialize; CheckError(nwIPX.result>0,$100); IOSocket:=$5678; IPXopenSocket(IOsocket,SHORT_LIVED_SOCKET); CheckError(nwIPX.result>0,$1000+nwIPX.result); { Setup of ECB and PepHeader, start listening for incoming packets. } LastTransactionID:=0; PacketReceived:=False; PEPSetupListenECB(Addr(ListenAndAckESR),IOsocket,@DataBuffer,546, ListenPepHdr,ListenECB); IPXListenForPacket(ListenECB); writeln('Listening for incoming packet.'); IPXGetIntervalMarker(ticks); REPEAT IPXrelinquishControl; IPXGetIntervalMarker(ticks2); CheckError(TimeOut(ticks,ticks2,130),$101);{ error if a timeout occurred } UNTIL PacketReceived; writeln('Packet received.. initiating transfer process.'); writeln('Received PacketID:',LastTransactionID); writeln('len of data:',BytesReceived); { do something with DataBuffer: the data that was just received. } { the first packet contains the filename and filesize } Move(DataBuffer[1],FileName[0],15); Move(DataBuffer[16],FileSize,4); writeln('Receiving file ',FileName,', size: ',FileSize); REPEAT { Listen for remaining packets } Packetreceived:=false; While SendECB.InuseFlag<>0 do IPXrelinquishControl; IPXListenForPacket(ListenECB); IPXGetIntervalMarker(ticks); writeln(FileSize); Repeat {write(lnr);} IPXrelinquishControl; IPXGetIntervalMarker(ticks2); CheckError(TimeOut(ticks,ticks2,10),$102); { error if Timeout occurred } until PacketReceived; writeln('Packet#:',LastTransactionID); writeln('len of data:',BytesReceived); FileSize:=FileSize-BytesReceived; { do something with DataBuffer: the data that was just received. } UNTIL (FileSize<=0); { entire file received } writeln('Transfer complete.'); IPXcloseSocket(IOsocket); end.