/*****************************************************************************
 *
 * Program Name:  SAMPLE.VAP
 *
 * Filename:	  sap.c
 *
 * Version:		  1.0
 *
 * Programmers:	  Bryan Sparks
 *
 * Files used:	  comm.h
 *
 * Comments:	  This is a "plug-in" sap module to do service advertising.
 *
 ****************************************************************************/
#include "comm.h"

/* We will keep this pointer around so as to keep track of the */
/* oscillating ECB.  We will need to know where it is later so we */
/* can cancel the event associated with that ECB. */
ECB		*DownECBPointer;

void		SAPWaitESRHandler();
void		SAPAdvertiseESRHandler();

SAPData		SAPDataEntity;
ECB			SAPECB;
IPXPacket	SAPPacket;

void StartSAPOscillationRoutines( ServerName, ServerType, ServerSocket )
char	ServerName[48];
int		ServerType;
unsigned int	ServerSocket;
{
	/* Initialize the variables for the SAP IPXPacket. */
	/* Notice that I broadcast on socket 452h (The SAP Socket) */
	/* You need not have the socket open to send on the socket. */
	SAPPacket.PacketType = (unsigned char)4;
	SAPPacket.PacketLength = IntSwap( sizeof( IPXPacket ) );
	IPXGetInternetworkAddress( (unsigned char *)SAPPacket.Destination.Network );
	memset( SAPPacket.Destination.Node, 0xFF, 6 );
	SAPPacket.Destination.Socket = 0x5204;

	/* I initialize the SAP data packet.  See the SAP document for details. */
	SAPDataEntity.InfoType = IntSwap( 2 );
	SAPDataEntity.ServerType = IntSwap( ServerType );
	strcpy( SAPDataEntity.ServerName, ServerName);
	IPXGetInternetworkAddress( (unsigned char *)SAPDataEntity.Address.Network );
	SAPDataEntity.IntermediateNetworks = IntSwap( 1 );
	SAPDataEntity.Address.Socket = ServerSocket;

	/* Initialize the ECB. */
	SAPECB.ESRAddress = (char far *)SAPWaitESRHandler;
	SAPECB.InUseFlag = 0;
	SAPECB.FragmentCount = 2;
	SAPECB.ECBSocket = 0x5204;
	memset( SAPECB.ImmediateAddress, 0xFF, 6 );
	SAPECB.FragmentDescriptor[0].Address = (char far *)&SAPPacket;
	SAPECB.FragmentDescriptor[0].Size = sizeof (IPXPacket );
	SAPECB.FragmentDescriptor[1].Address = (char far *)&SAPDataEntity;
	SAPECB.FragmentDescriptor[1].Size = sizeof( SAPData );

	IPXSendPacket( &SAPECB );

}


/* These two ESRs require some explanation. */
/* When the IPXSendPacket is done above the ESR SAPWaitESR will be called */
/* This ESR will immediately change the ESR to SAPAdvertiseESR and waits */
/* one minute.  In one minute the SAPAdvertiseESR will be activated and */
/* it will change the ESR to SAPWaitESR and then do a send packet. */
/* These two ESRs will oscillate back and forth thus doing SAP calls. */
void SAPWaitESR( wECB )
ECB		*wECB;
{
	wECB->ESRAddress = (char far *)SAPAdvertiseESRHandler;
	IPXScheduleIPXEvent( 60*18, wECB );		/* Every 60 Seconds */
}


void SAPAdvertiseESR( wECB )
ECB		*wECB;
{
	wECB->ESRAddress = (char far *)SAPWaitESRHandler;
	IPXSendPacket( wECB );
}


int StopSAPOscillationRoutines( ServerName, ServerType, ServerSocket )
char	ServerName[48];
int		ServerType;
unsigned int	ServerSocket;
{
	SAPData		wDataEntity;
	ECB			wECB;
	IPXPacket	wPacket;


	/* First we will cancel the SAP oscillation ESRs. */
	IPXCancelEvent( &SAPECB );
	while (SAPECB.InUseFlag)
		;

	/* Was the event canceled?  FC means yes. */
	if (SAPECB.CompletionCode != 0xFC) 
		return (-1);

	/* Now we will send out a IPX packet telling everyone that this */
	/* server is down.  See the SAP document for details. */
	wPacket.PacketType = (unsigned char)4;
	wPacket.PacketLength = IntSwap( sizeof( IPXPacket ) );
	IPXGetInternetworkAddress( (unsigned char *)wPacket.Destination.Network );
	memset( wPacket.Destination.Node, 0xFF, 6 );
	wPacket.Destination.Socket = 0x5204;

	/* I initialize the SAP data packet.  See the SAP document for details. */
	/* Tell everyone that I am going down. (Thus the 16 intermediate networks) */
	wDataEntity.InfoType = IntSwap( 2 );
	wDataEntity.ServerType = IntSwap( ServerType );
	strcpy( wDataEntity.ServerName, ServerName);
	IPXGetInternetworkAddress( (unsigned char *)wDataEntity.Address.Network );
	wDataEntity.IntermediateNetworks = IntSwap( 16 );
	wDataEntity.Address.Socket = ServerSocket;

	/* Initialize the ECB. */
	wECB.FragmentCount = 2;
	wECB.ECBSocket = 0x5204;
	memset( wECB.ImmediateAddress, 0xFF, 6 );
	wECB.FragmentDescriptor[0].Address = (char far *)&wPacket;
	wECB.FragmentDescriptor[0].Size = sizeof (IPXPacket );
	wECB.FragmentDescriptor[1].Address = (char far *)&wDataEntity;
	wECB.FragmentDescriptor[1].Size = sizeof( SAPData );

	IPXSendPacket( &wECB );
	while( wECB.InUseFlag )
		;

	return (0);
}











