home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
dax1.exe
/
DAP
/
DAPA
/
DAPSEND.C
< prev
next >
Wrap
Text File
|
1992-07-15
|
9KB
|
184 lines
// ╔════════════════════════════════════════════════════════════════════╗
// ║ ║
// ║ module: dapsend.c ║
// ║ abstract: This module contains the code to send requests to ║
// ║ our server application. This routines is the 'guts' ║
// ║ of the DAP Layer on the client side. This is where ║
// ║ we implement things like retries, sequencing, etc. ║
// ║ ║
// ║ environment: NetWare 3.x v3.11 ║
// ║ Network C for NLMs SDK ║
// ║ CLib v3.11 ║
// ║ Network C for DOS v2.0 ║
// ║ NetWare C Interface DOS v1.2 ║
// ║ ║
// ║ This software is provided as is and carries no warranty ║
// ║ whatsoever. Novell disclaims and excludes any and all implied ║
// ║ warranties of merchantability, title and fitness for a particular ║
// ║ purpose. Novell does not warrant that the software will satisfy ║
// ║ your requirements or that the software is without defect or error ║
// ║ or that operation of the software will be uninterrupted. You are ║
// ║ using the software at your risk. The software is not a product ║
// ║ of Novell, Inc. or any of subsidiaries. ║
// ║ ║
// ╟────────────────────────────────────────────────────────────────────╢
// ║ maintenance history: ║
// ║ level date pi description ║
// ╟────────────────────────────────────────────────────────────────────╢
// ║ 001 01/24/92 kl initial release. ║
// ║ 002 07/14/92 kl windows port. add a delay() for Windows ║
// ╚════════════════════════════════════════════════════════════════════╝
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
#include "cp/cpapi.h"
#include "dap/dapsys.h"
#if defined(WINCLIENT)
#define delay(x) __dsdelay(x)
extern void FAR PASCAL IPXYield(void);
void __dsdelay(unsigned milliseconds)
{
clock_t start = clock();
unsigned ticks = milliseconds / 55;
//
// wrote this, since delay() isn't in Windows...
//
// I'm approximating everything here, but this API really isn't
// too important. I will always wait at least 1 tick, regardless
// of how many milliseconds you asked for. I'm assuming that
// there are 55 milliseconds in a clock tick...
//
while( (clock() - start) <= ticks ) IPXYield();
}
#endif
T_RC DAPSendRequest(DAPDATA *DAPid, UINT16 requestCode)
{
WORD RetryCount = DAPid->retryCount;
WORD ResponseDelay;
//
// Init the common DAP fields
//
DAPid->dapRequest.packetType = DAPSERVICEREQUEST;
DAPid->dapRequest.sequence = DAPid->nextSequence++;
DAPid->dapRequest.sessionID = DAPid->sessionID;
DAPid->dapRequest.requestCode = requestCode;
//
// Send the request, wait for a reply
//
DAPid->timesTried = 0;
DAPid->sendFailed = 0;
while( RetryCount-- ){
//
// Try to send the message to the server
//
// Let the DAP Layer on the server side know how many times
// we've retried this request...
//
DAPid->dapRequest.timesTried = DAPid->timesTried++;
//!!
// This can cause us to register twice, if the first packet
// is lost somewhere. If the server really registered us,
// but we lost the reply, we will register again here...
//
// If we made the server smart enought to handle this, however
// and automatically handle this. like maybe ignore the 2nd
// request for the same thing, if the response hasn't yet
// been sent.
//
// could make the server send an immediate reply back to the
// client, telling him about this situation. the client
// could detect this, and provide some sort of intelligent
// handling.
//
// have a constant (NUMBERTIMESTORETRYWHENBUSY) to control this.
//
// try a reset_router console command to try and force this
// error!!!
//!!
if( CPSendMessage(DAPid->CPid,&DAPid->dapRequest,sizeof DAPid->dapRequest) ){
DAPid->sendFailed++;
continue;
}
//
// Wait for a response to come in
//
ResponseDelay = DAPid->responseDelay;
while( ResponseDelay-- ){
if( CPRecvMessage(DAPid->CPid,&DAPid->dapReply,sizeof DAPid->dapReply) == 0 ){
switch(DAPid->dapReply.packetType){
//
// A ServiceReply is what we are waiting for. Just
// make sure the sequence number is correct.
//
case DAPSERVICEREPLY:
//
// Make sure we got what we were expecting
//
if( DAPid->dapRequest.sequence != DAPid->dapReply.sequence ){
xDIAG1(DAPprintf("\nGot %lx. Expecting %lx.\n",
DAPid->dapReply.sequence,
DAPid->dapRequest.sequence));
//!!return DAP_PACKET_OUT_OF_SEQ;
//
// Let's just wait for the correct one...
//
break;
}
//!!
// If server is telling us that he is busy,
// retry without penalizing the response delay.
// can use the state info to determine if we
// are not in the sending state. if so, ignore
// packet. !! cannot queue the reply, cause
// the links will be used by other threads!
// can have a STATEREPLY packet which can be
// expidited thru the system. it would use
// a 'canned reply' to the client in question.
// don't reset the state until you know the
// reply has been sent, and then you'll know
// it is okay to accept another request! This
// way, we can just print an information message
// saying we received a 'duplicate' request
// and go on.
//
//!!
return DAPid->dapReply.returnCode;
break;
#if 0
//
// We'll need this later, when we allow the server
// to send requests to us...
//
// A ServiceRequest has been received from the server.
// Pass this data off to the routine that can deal
// with the request, and then look for our reply.
//
case DAPSERVICEREQUEST:
DAPHandleServiceRequest((DAPRequest *)&DAPid->dapReply);
break;
#endif
//
// We got something we weren't expecting...
//
default:
return DAP_INTERNAL_ERROR;
break;
}
}
delay(112); // wait just 2 ticks and try again
}
delay(112); // wait before trying again
}
return (DAPid->sendFailed == DAPid->timesTried)
? DAP_SEND_FAILURE
: DAP_TIMEOUT;
}