home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ibmtool.zip
/
indic.c
< prev
next >
Wrap
Text File
|
1997-11-07
|
14KB
|
391 lines
/******************************************************************************/
/* */
/* FILE: INDIC.C */
/* */
/* PURPOSE: This file contains the Indications processing. */
/* */
/* FUNCTIONS: CheckIndications */
/* CheckControlFrame */
/* TTXmitConfirm */
/* TTReceiveLookahead */
/* TTIndicationComplete */
/* TTReceiveChain */
/* TTStatusIndication */
/* TTGenReqConf */
/* */
/* GLOBAL DATA ACCESSED */
/* char *RetStr[] */
/* char *GenReqStr[] */
/* BOOLEAN Echo, */
/* ServerStressAck, */
/* WkstaResponded */
/* USHORT ReqHandle, */
/* LastStatus, */
/* WkstaStressCnt */
/* WORD IndicationCount, */
/* LastFrameSize, */
/* LastLookahead */
/* CTRLFRAME ControlFrame */
/* */
/******************************************************************************/
#define INCL_SUB
#define INCL_BASE
#define INCL_DOS
#include <os2.h>
#include <stdio.h>
#include <stdarg.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "ndis.h"
#include "ibmtool.h"
#include "ioctl.h"
BOOLEAN StartWkstaStress = FALSE;
WORD CheckIndications ()
{
INDICQ IndicQElem;
while (WedgeCommon->CurrIndic != WedgeCommon->NextFreeIndic)
{
IndicQElem = WedgeCommon->IndicQueue[WedgeCommon->CurrIndic];
if (++WedgeCommon->CurrIndic == INDIC_QUEUE_SIZE)
WedgeCommon->CurrIndic = 0;
++IndicationCount;
++IndicCnt.Total;
switch (IndicQElem.IndicType)
{
case TRANSMITCONFIRM:
++IndicCnt.Tx;
TTXmitConfirm (IndicQElem);
break;
case RECEIVELOOKAHEAD:
++IndicCnt.Rx;
_fmemcpy ((void far *) ControlFrame.pBuffer,
(void far *) WedgeCommon->RcvData,
MAX_IMMED_LEN);
TTReceiveLookahead (IndicQElem);
break;
case INDICATIONCOMPLETE:
++IndicCnt.Comp;
TTIndicationComplete (IndicQElem);
break;
case RECEIVECHAIN:
++IndicCnt.Rx;
_fmemcpy ((void far *) ControlFrame.pBuffer,
(void far *) WedgeCommon->RcvData,
MAX_IMMED_LEN);
TTReceiveChain (IndicQElem);
break;
case STATUSINDICATION:
++IndicCnt.Stat;
TTStatusIndication (IndicQElem);
break;
case GENREQCONF:
++IndicCnt.GenReq;
TTGenReqConf (IndicQElem);
break;
} /* endswitch */
return IndicQElem.IndicType;
} /* endif */
if (StartWkstaStress)
{
StartWkstaStress = FALSE;
StressWksta ();
}
return 0;
}
int CheckControlFrame ()
{
// check the Receive Data Buffer (RcvData) for control frames
char cmd[80], *p;
BYTE far *data;
int i, offset, opcode = 0;
if (!strncmp ((char *) ControlFrame.pID, "IBM", 3))
{
_fmemset (ControlFrame.pID, 0, 4);
// we got a control frame
opcode = (int) *(int *) (ControlFrame.pOpCode);
switch (opcode)
{
case CCWKSTA:
// Broadcast Control Frame: WORKSTATION -> SERVER
// Tells the SERVER the WORKSTATION's address
// if we're a Server
// 1) add this workstation to the list of workstations and
// 2) send out a control frame directed to the workstation
// to let him know this server's address
if (WedgeCommon->RspMode == SERVER)
{
AddWorkStation ();
DosSleep (1000);
SendControlFrame (CCSERVER);
}
break;
case CCSERVER:
// Directed Control Frame: SERVER -> WORKSTATION
// Tells the WORKSTATION the SERVER's address
// if we're a Workstation,
// copy the Source Address into WedgeCommon->ServerAddr
if (WedgeCommon->RspMode == WORKSTATION)
{
_fmemcpy ((void far *) WedgeCommon->ServerAddr,
(void far *) ControlFrame.pSrc,
WedgeCommon->StnAdrSz);
} /* endif */
break;
case CCSTRESS:
// Broadcast Control Frame: SERVER -> WORKSTATIONs
// Tells WORKSTATIONs to start stressing
if (WedgeCommon->RspMode == WORKSTATION && !WedgeCommon->StressMode)
{
DosSleep (1000);
PrintMsg (RED, "CCSTRESS received");
hexprint (ControlFrame.pBuffer, 64, 0);
StartWkstaStress = TRUE;
}
break;
case CCXMIT:
// Directed Control Frame: WORKSTATION -> SERVER
// Tells SERVER to transmit frame(s) to the WORKSTATION.
// (Essentially a MULTRAN command to the SERVER.)
if (WedgeCommon->RspMode == SERVER)
{
strcpy (cmd, "MULTRAN ");
/* get the data out of the frame */
data = (BYTE far *) ControlFrame.pData;
// get the frame count (required)
sprintf (cmd + 8, "%ld ", *(DWORD *) data);
p = cmd + strlen (cmd);
data += sizeof (DWORD);
// get the Min (required)
sprintf (p, "%ld ", *(DWORD *) data);
p = cmd + strlen (cmd);
data += sizeof (DWORD);
// get the Max (required)
sprintf (p, "%ld ", *(DWORD *) data);
p = cmd + strlen (cmd);
data += sizeof (DWORD);
// get Type - if DIRECTED, fill in Type and NetAddr
if (*(WORD *) data == DIRECTED)
{
sprintf (p, "%d ", *(WORD *) data);
p = cmd + strlen (cmd);
data += sizeof (WORD);
// frame is directed to the given address
for (i=0; i<WedgeCommon->StnAdrSz; ++i, p+=3, ++data)
sprintf (p, "%02X ", *(BYTE *) data);
}
else if (*(WORD *) data == DIRECTED_TO_WKSTA)
{
sprintf (p, "%d ", *(WORD *) data);
p = cmd + strlen (cmd);
data = (BYTE far *) ControlFrame.pSrc;
// frame is directed to the workstation
// sending the control frames
for (i=0; i<WedgeCommon->StnAdrSz; ++i, p+=3, ++data)
sprintf (p, "%02X ", *(BYTE *) data);
}
// call MULTRAN with command parameters set up
ParseCommand (cmd);
}
break;
case CCDELWKSTA:
// Directed Control Frame: WORKSTATION -> SERVER
// Workstation is logging off
// If we're a SERVER,
// Delete the workstation from the list
if (WedgeCommon->RspMode == SERVER)
{
PrintMsg (RED, "CCDELWKSTA received");
hexprint (ControlFrame.pBuffer, 64, 0);
DeleteWorkStation ();
}
break;
case CCENDSTRESS:
// Directed Control Frame: WORKSTATION -> SERVER
// Tells the SERVER the WORKSTATION is finished stressing.
// If we're a SERVER,
// 1) Acknowledge the WORKSTATION
// 2) Decrement number of WORKSTATIONs stressing
if (WedgeCommon->RspMode == SERVER)
{
PrintMsg (RED, "CCENDSTRESS received");
hexprint (ControlFrame.pSrc, MACMSC.MscStnAdrSz, 0);
StopWkStaStress ();
SendControlFrame (CCENDSTRESSACK);
}
break;
case CCENDSTRESSACK:
// Directed Control Frame: SERVER -> WORKSTATION
// Acknowledges the WORKSTATION's ENDSTRESS frame.
PrintMsg (RED, "CCENDSTRESSACK received");
case CCSRVSTOP:
// Broadcast Control Frame: SERVER -> WORKSTATIONs
// Tells WORKSTATION's that SERVER has ended stress test.
if (opcode == CCSRVSTOP)
PrintMsg (RED, "CCSRVSTOP received");
// If we're a WORKSTATION,
// Cease sending ENDSTRESS
if (WedgeCommon->RspMode == WORKSTATION)
ServerStressAck = TRUE;
break;
case CCQUERYWKSTA:
// Directed Control Frame: SERVER -> WORKSTATION
// Asks WORKSTATIONs to respond.
// If we're a WORKSTATION,
// Send a CCQUERYACK frame back to the SERVER
if (WedgeCommon->RspMode == WORKSTATION)
{
PrintMsg (RED, "CCQUERYWKSTA received");
hexprint (ControlFrame.pDest, 2 * MACMSC.MscStnAdrSz, 0);
SendControlFrame (CCQUERYACK);
}
break;
case CCQUERYACK:
// Directed Control Frame: WORKSTATION -> SERVER
// Acknowledges the SERVER's QUERYWKSTA frame.
// If we're a SERVER,
// Check the WORKSTATION list
if (WedgeCommon->RspMode == SERVER)
{
PrintMsg (RED, "CCQUERYACK received");
hexprint (ControlFrame.pDest, 2 * MACMSC.MscStnAdrSz, 0);
WkstaResponded = TRUE;
}
break;
} /* endswitch */
}
return opcode;
}
int TTXmitConfirm (INDICQ IndicQElem)
{
LastStatus = IndicQElem.Parm[1];
PrintMsg (0, "TransmitConfirm: Status = %s Handle = %u",
RetStr[LastStatus], IndicQElem.Parm[0]);
UpdateInfo ();
return SUCCESS;
}
int TTReceiveLookahead (INDICQ IndicQElem)
{
LastFrameSize = IndicQElem.Parm[0];
LastLookahead = IndicQElem.Parm[1];
PrintMsg (0, "ReceiveLookahead: FrameSize = %d Lookahead = %d",
LastFrameSize, LastLookahead);
if (!CheckControlFrame () && Echo)
{
// echo the received frame back to the sender
PrimEcho ();
}
UpdateInfo ();
//if (WedgeCommon->TotalRxErr && WedgeCommon->CheckData)
// {
// WedgeCommon->TotalRxErr = 0L;
// PrintMsg (RED, "Data Error in Received Frame");
// }
return SUCCESS;
}
int TTIndicationComplete (INDICQ IndicQElem)
{
PrintMsg (0, "Indication Complete");
return SUCCESS;
}
int TTReceiveChain (INDICQ IndicQElem)
{
LastFrameSize = IndicQElem.Parm[0];
LastLookahead = IndicQElem.Parm[1];
PrintMsg (0, "Receive Chain: FrameSize = %d Handle = %u",
LastFrameSize, LastLookahead);
CheckControlFrame ();
UpdateInfo ();
//if (WedgeCommon->TotalRxErr)
// {
// WedgeCommon->TotalRxErr = 0L;
// PrintMsg (RED, "Data Error in Received Frame");
// }
return SUCCESS;
}
int TTStatusIndication (INDICQ IndicQElem)
{
switch (IndicQElem.Parm[1])
{
case RINGSTATUS:
++IndicCnt.RingStatus;
PrintMsg (0, "Ring Status Indication: %04X", IndicQElem.Parm[0]);
break;
case ADAPTERCHECK:
++IndicCnt.AdapterCheck;
PrintMsg (0, "Adapter Check Indication: %04X", IndicQElem.Parm[0]);
break;
case STARTRESET:
++IndicCnt.StartReset;
PrintMsg (0, "MAC Start Reset Indication");
break;
case ENDRESET:
++IndicCnt.EndReset;
PrintMsg (0, "MAC End Reset Indication");
break;
case INTERRUPT:
++IndicCnt.Interrupt;
PrintMsg (0, "Interrupt Indication");
break;
} /* endswitch */
return SUCCESS;
}
int TTGenReqConf (INDICQ IndicQElem)
{
LastStatus = IndicQElem.Parm[1];
PrintMsg (0, "General Request Confirmation: %s",
GenReqStr[IndicQElem.Parm[2] - 1]);
PrintMsg (0, " Handle %u", IndicQElem.Parm[0]);
PrintMsg (0, " Status %s", RetStr[LastStatus]);
return SUCCESS;
}