316 lines
9.0 KiB
ObjectPascal
316 lines
9.0 KiB
ObjectPascal
{$B-,V-,X+}
|
|
|
|
UNIT nwSPX;
|
|
|
|
{ nwSPX unit as of 950301 / NwTP 0.6 API. (c) 1993,1995, R. Spronk }
|
|
{ NOTE: These SPX calls are not documented in this version }
|
|
|
|
INTERFACE
|
|
|
|
Uses Dos,nwMisc,nwIPX;
|
|
|
|
{ Primary SPX calls: Subf: Comments:
|
|
|
|
SPXabortConnection 14
|
|
SPXGetConnectionStatus 15
|
|
SPXestablishConnection 11
|
|
* SPXinitialize 10
|
|
SPXlistenForConnection 12
|
|
SPXlistenForSequencedPacket 17
|
|
SPXsendSequencedPacket 16
|
|
SPXTerminateConnection 13
|
|
|
|
Secondary calls:
|
|
|
|
* SPXpresent
|
|
|
|
Notes: (1) These functions use INT 21 and are not to be called from
|
|
within an ESR.
|
|
}
|
|
|
|
Var Result:word; { unit errorcode variable }
|
|
|
|
Type TspxHeader=Record
|
|
IPXhdr :TipxHeader; { SPX will set packetType to 5 }
|
|
connControl :byte; { rarely used, set to $00 }
|
|
{ ignored by SPX, but passed on to receiver:
|
|
$10 End of message; $20 Attention packet }
|
|
dataStreamType:Byte; { to be used by higher level protocols.
|
|
nust be < $FE, passed on to receiver }
|
|
sourceConnId,
|
|
destConnId :Word;
|
|
sequenceNbr,
|
|
acknowledgeNbr,
|
|
allocationNbr :Word;
|
|
end;
|
|
{ Fields within IPX and SPX are high-low. Byte swapping will be done
|
|
by the IPX functions, except network and node addresses. }
|
|
|
|
Type TSPXconnectionInformation
|
|
=record
|
|
ConnectionState :Byte; { all fields are returned hi-lo }
|
|
WatchDogState :Byte;
|
|
LocalSPXConnectionId :Word;
|
|
RemoteSPXConnectionId :Word;
|
|
SequenceNumber :Word;
|
|
LocalAcknowledgeNumber :Word;
|
|
LocalAllocationNumber :Word;
|
|
RemoteAcknowledgeNumber:Word;
|
|
RemoteAllocationNumber :Word;
|
|
LocalSocket :Word;
|
|
ImmediateAddress :TnodeAddress;
|
|
RemoteAddress :TinterNetworkAddress;
|
|
RetransmissionCount :Word;
|
|
EstimatedRoundTripDelay:Word;
|
|
RetransmittedPackets :Word;
|
|
SuppressedPackets :Word;
|
|
end;
|
|
|
|
Function SPXpresent:boolean;
|
|
{ Determines if SPX is installed. Calls SPXInitialize. }
|
|
|
|
{IPX/SPX: 10h}
|
|
Function SpxInitialize(Var SPXhiVer,SPXloVer:Byte;
|
|
Var MaxConn,AvailConn:word):boolean;
|
|
{ Determines if SPX is loaded. (this function also tests the presence of IPX, }
|
|
{ as IPX is required for running SPX. Remember: Netware 2.2 allows IPX and SPX }
|
|
{ to be loaded seperately, so only IPX may be present. }
|
|
|
|
{IPX/SPX: 11h}
|
|
Function SPXestablishConnection(retryCount:byte; WatchdogFlag:Byte;
|
|
{i/o} Var ECB:Tecb;
|
|
{out} Var SPXconnectionID:Word):boolean;
|
|
|
|
{IPX/SPX: 12h}
|
|
Function SPXlistenForConnection(retryCount:Byte; WatchdogFlag: Byte;
|
|
Var ECB:Tecb ):boolean;
|
|
|
|
{IPX/SPX: 15h}
|
|
Function SPXGetConnectionStatus(SPXconnectionID:word;
|
|
Var connInfo:TSPXconnectionInformation):boolean;
|
|
|
|
{IPX/SPX: 13h}
|
|
Function SPXTerminateConnection(SPXconnectionID:Word; ECB:Tecb):boolean;
|
|
|
|
{IPX/SPX: 14h}
|
|
Function SPXabortConnection(SPXconnectionID:Word):boolean;
|
|
|
|
{IPX/SPX: 16h}
|
|
Function SPXsendSequencedPacket(SPXconnectionID:Word; Var ECB:Tecb):boolean;
|
|
|
|
{IPX/SPX: 17h}
|
|
Function SPXlistenForSequencedPacket(Var ECB:Tecb):boolean;
|
|
|
|
{************** Secondary Procedures ***************************************}
|
|
|
|
IMPLEMENTATION {==============================================================}
|
|
|
|
CONST
|
|
SPX_WATCHDOG_ENABLED =1;
|
|
SPX_WATCHDOG_DISABLED =0;
|
|
SPX_DEFAULT_RETRY_COUNT =0;
|
|
|
|
SPX_POOL_SIZE =10;
|
|
|
|
SPX_MAX_DATA_LENGTH =534;
|
|
|
|
{IPX/SPX: 10 }
|
|
Function SpxInitialize(Var SPXhiVer,SPXloVer:Byte;
|
|
Var MaxConn,AvailConn:word):boolean;
|
|
Var Regs:registers;
|
|
begin
|
|
With regs
|
|
do begin
|
|
al:=$00;
|
|
bx:=$0010;
|
|
IpxSpxSystemCall(Regs);
|
|
result:=regs.al;
|
|
|
|
if AL<>$FF
|
|
then begin
|
|
result:=$FF;
|
|
SpxInitialize:=false
|
|
end
|
|
else begin
|
|
SPXhiVer:=BH;
|
|
SPXloVer:=BL;
|
|
MaxConn:=CX;
|
|
AvailConn:=DX;
|
|
result:=$00;
|
|
SpxInitialize:=true;
|
|
end;
|
|
end; {with}
|
|
{ resultcodes: $00 successfull (SPX installed); $FF SPX not installed }
|
|
end;
|
|
|
|
Function SpxPresent:boolean;
|
|
Var SpxHi,SpxLo:Byte;
|
|
MaxConn,AvConn:word;
|
|
begin
|
|
SpxPresent:=( IpxPresent and SpxInitialize(SpxHi,SpxLo,MaxConn,AvConn) );
|
|
end;
|
|
|
|
{IPX/SPX: 11h}
|
|
Function SPXestablishConnection(retryCount:byte; WatchdogFlag:Byte;
|
|
{i/o} Var ECB:Tecb;
|
|
{out} Var SPXconnectionID:Word):boolean;
|
|
Var regs:registers;
|
|
begin
|
|
With regs
|
|
do begin
|
|
BX:=$0011;
|
|
AL:=retryCount;
|
|
AH:=WatchDogFlag;
|
|
ES:=Seg(ECB);
|
|
SI:=ofs(ECB);
|
|
end;
|
|
IpxSpxSystemCall(Regs);
|
|
result:=regs.AL;
|
|
SPXconnectionID:=regs.DX;
|
|
SPXestablishConnection:=(result=$00);
|
|
{ resultcodes: $00 SPX Attempting to contact destination socket;
|
|
$EF Local connection table full;
|
|
$FD Fragment count not 1 AND/OR Buffer size not 42;
|
|
$FF Send Socket not open OR IPX/SPX not initialized. }
|
|
end;
|
|
|
|
|
|
{IPX/SPX: 12h}
|
|
Function SPXlistenForConnection(retryCount:Byte; WatchdogFlag: Byte;
|
|
Var ECB:Tecb ):boolean;
|
|
Var regs:Registers;
|
|
begin
|
|
With regs
|
|
do begin
|
|
BX:=$0012;
|
|
AL:=retryCount;
|
|
AH:=WatchdogFlag;
|
|
ES:=Seg(ECB);
|
|
SI:=Ofs(ECB);
|
|
IpxSpxSystemCall(Regs);
|
|
result:=AL;
|
|
if result<>$FF
|
|
then result:=$00;
|
|
end;
|
|
SPXlistenForConnection:=(result=$00);
|
|
end;
|
|
|
|
{IPX/SPX: 15h}
|
|
Function SPXGetConnectionStatus(SPXconnectionID:word;
|
|
Var connInfo:TSPXconnectionInformation):boolean;
|
|
Var regs:Registers;
|
|
begin
|
|
With regs
|
|
do begin
|
|
BX:=$0015;
|
|
DX:=SPXconnectionID;
|
|
ES:=Seg(connInfo);
|
|
SI:=Ofs(connInfo);
|
|
IpxSpxSystemCall(Regs);
|
|
Result:=AL;
|
|
end;
|
|
if result=0
|
|
then begin
|
|
With ConnInfo
|
|
do begin { force all returned words lo-hi }
|
|
LocalSPXConnectionId :=Swap(LocalSPXconnectionID);
|
|
RemoteSPXConnectionId :=Swap(RemoteSPXconnectionID);
|
|
SequenceNumber :=swap(SequenceNumber);
|
|
LocalAcknowledgeNumber :=swap(LocalAcknowledgeNumber);
|
|
LocalAllocationNumber :=swap(LocalAllocationNumber);
|
|
RemoteAcknowledgeNumber:=swap(RemoteAcknowledgeNumber);
|
|
RemoteAllocationNumber :=swap(RemoteAllocationNumber);
|
|
LocalSocket :=swap(LocalSocket);
|
|
RemoteAddress.socket :=swap(remoteAddress.socket);
|
|
RetransmissionCount :=swap(RetransmissionCount);
|
|
EstimatedRoundTripDelay:=swap(EstimatedRoundTripDelay);
|
|
RetransmittedPackets :=swap(RetransmittedPackets);
|
|
SuppressedPackets :=swap(SuppressedPackets);
|
|
end;
|
|
end;
|
|
SPXGetConnectionStatus:=(result=0);
|
|
{ Resulcodes: $00 Connection is active; $EE No such connection }
|
|
end;
|
|
|
|
|
|
{IPX/SPX: 13h}
|
|
Function SPXTerminateConnection(SPXconnectionID:Word; ECB:Tecb):boolean;
|
|
Var regs:Registers;
|
|
begin
|
|
with regs
|
|
do begin
|
|
BX:=$0013;
|
|
DX:=SPXconnectionID;
|
|
ES:=seg(ECB);
|
|
SI:=Ofs(ECB);
|
|
end;
|
|
IpxSpxSystemCall(Regs);
|
|
result:=regs.al;
|
|
if result<>$FF
|
|
then result:=$00;
|
|
SPXterminateConnection:=(result=0);
|
|
{resultcodes: $00 SPX attempting to break connection;
|
|
$FF IPX/SPX not loaded. }
|
|
end;
|
|
|
|
{IPX/SPX: 14h}
|
|
Function SPXabortConnection(SPXconnectionID:Word):boolean;
|
|
Var regs:Registers;
|
|
begin
|
|
with regs
|
|
do begin
|
|
BX:=$0014;
|
|
DX:=SPXconnectionID;
|
|
end;
|
|
IpxSpxSystemCall(Regs);
|
|
result:=regs.al;
|
|
if result<>$FF
|
|
then result:=$00;
|
|
SPXabortConnection:=(result=0);
|
|
{resultcodes: $00 SPX trying to unilateral break the connection;
|
|
$FF IPX/SPX not loaded. }
|
|
end;
|
|
|
|
{IPX/SPX: 16h}
|
|
Function SPXsendSequencedPacket(SPXconnectionID:Word; Var ECB:Tecb):boolean;
|
|
Var regs:Registers;
|
|
begin
|
|
with regs
|
|
do begin
|
|
BX:=$0016;
|
|
DX:=SPXconnectionID;
|
|
ES:=Seg(ECB);
|
|
SI:=Ofs(ECB);
|
|
end;
|
|
IpxSpxSystemCall(Regs);
|
|
result:=regs.al;
|
|
if result<>$FF
|
|
then result:=$00;
|
|
SPXsendSequencedPacket:=(result=0);
|
|
{resultcodes: $00 SPX will attempt to send packet;
|
|
$FF IPX/SPX not loaded. }
|
|
end;
|
|
|
|
{IPX/SPX: 17h}
|
|
Function SPXlistenForSequencedPacket(Var ECB:Tecb):boolean;
|
|
Var regs:Registers;
|
|
begin
|
|
with regs
|
|
do begin
|
|
BX:=$0017;
|
|
ES:=Seg(ECB);
|
|
SI:=Ofs(ECB);
|
|
end;
|
|
IpxSpxSystemCall(Regs);
|
|
result:=regs.al;
|
|
if result<>$FF
|
|
then result:=$00;
|
|
SPXlistenForSequencedPacket:=(result=0);
|
|
{resultcodes: $00 SPX waits for incoming packets;
|
|
$FF IPX/SPX not loaded. }
|
|
end;
|
|
|
|
{************** Secondary Procedures ***************************************}
|
|
|
|
end.
|