home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ibmtool.zip
/
prim.c
< prev
next >
Wrap
Text File
|
1997-11-07
|
30KB
|
929 lines
/******************************************************************************/
/* */
/* FILE: PRIM.C */
/* */
/* PURPOSE: This file contains the MAC Primitive processing. */
/* */
/* FUNCTIONS: InitXmit */
/* TTUseGDT */
/* TTSetTxBuffSize */
/* TTEditBuffer */
/* TTDispXmitBuf */
/* TTXmit */
/* TTMultipleXmit */
/* TTIndicationsOff */
/* TTIndicationsOn */
/* SendControlFrame */
/* PrimEcho */
/* */
/* GLOBAL DATA ACCESSED */
/* char *RetStr[] */
/* BOOLEAN TokenRing */
/* BOOLEAN Debug */
/* USHORT ReqHandle */
/* USHORT LastStatus */
/* USHORT DOSVersion */
/* WORD LastFrameSize */
/* ULONG hWedge */
/* SERVICECHAR MACMSC */
/* 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"
#define PHYS_ADDR 0
#define GDT_ADDR 2
#define TRAN 0
#define MTRAN 1
#define CTRL 2
#define ONEK 1024
#define SEGSIZE 0xFFFF
#define HALFSEG SEGSIZE >> 1
#define HALFSEGPLUS HALFSEG + ONEK
typedef struct _TXDESC {
BYTE far *pDest;
BYTE far *pSrc;
BYTE far *pLen;
BYTE far *pOpCode;
BYTE far *pData;
TXBUFDESC TxBufDesc;
} TXDESC;
typedef struct _TXCHAINSTR {
WORD ReqHandle;
TXBUFDESC far *TxBuffDescPtr;
} TXCHAINSTR;
TXCHAINSTR TxChain;
TXDESC TxDesc[3];
BYTE BroadcastAddr[ADDR_LEN];
int InitXmit ()
{
int i, offset;
IOCTLDATA IOData;
IOCTLDATA far *IODataPtr = &IOData;
/* initialize the broadcast address */
for (i=0; i<ADDR_LEN; ++i) BroadcastAddr[i] = 0xFF;
/*** initialize the TRAN Tx Buffer Descriptor ***/
TxDesc[TRAN].TxBufDesc.TxImmedLen = MAX_IMMED_LEN;
TxDesc[TRAN].TxBufDesc.TxImmedPtr =
(BYTE far *) _fcalloc (MAX_IMMED_LEN, sizeof (BYTE));
_fmemset ((void far *) TxDesc[TRAN].TxBufDesc.TxImmedPtr, 0, MAX_IMMED_LEN);
for (i=0; i<MAX_TX_DATABLK; ++i)
TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxRsvdByte = 0;
TxDesc[TRAN].TxBufDesc.TxDataCnt = 0;
offset = 0;
if (TokenRing) offset = 2;
TxDesc[TRAN].pDest = (TxDesc[TRAN].TxBufDesc.TxImmedPtr + offset);
TxDesc[TRAN].pSrc = (TxDesc[TRAN].TxBufDesc.TxImmedPtr + offset +
MACMSC.MscStnAdrSz);
TxDesc[TRAN].pLen = TxDesc[TRAN].pSrc + MACMSC.MscStnAdrSz;
/*** initialize the MTRAN Tx Buffer Descriptor ***/
TxDesc[MTRAN].TxBufDesc.TxImmedLen = WedgeCommon->HeaderLen;
TxDesc[MTRAN].TxBufDesc.TxImmedPtr =
(BYTE far *) _fcalloc (MACMSC.MscMaxFrame, sizeof (BYTE));
TxDesc[MTRAN].TxBufDesc.TxDataCnt = 1;
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxRsvdByte = 0;
TxDesc[MTRAN].pData = TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr =
TxDesc[MTRAN].TxBufDesc.TxImmedPtr + WedgeCommon->HeaderLen;
for (i=0; i<MACMSC.MscMaxFrame; ++i)
TxDesc[MTRAN].TxBufDesc.TxImmedPtr[MACMSC.MscMaxFrame-i-1] =
(BYTE) ((i + 1) & 0xFF);
offset = 0;
if (TokenRing)
{
TxDesc[MTRAN].TxBufDesc.TxImmedPtr[offset++] = 0x10;
TxDesc[MTRAN].TxBufDesc.TxImmedPtr[offset++] = 0x40;
}
TxDesc[MTRAN].pDest = (TxDesc[MTRAN].TxBufDesc.TxImmedPtr + offset);
TxDesc[MTRAN].pSrc = (TxDesc[MTRAN].TxBufDesc.TxImmedPtr + offset +
MACMSC.MscStnAdrSz);
TxDesc[MTRAN].pLen = TxDesc[MTRAN].pSrc + MACMSC.MscStnAdrSz;
// restore the GDT address
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr = TxDesc[MTRAN].pData;
// put in the Broadcast Address as the Destination
_fmemcpy ((void far *) TxDesc[MTRAN].pDest,
(void far *) BroadcastAddr, 6);
/* initialize the CTRL Tx Buffer Descriptor */
TxDesc[CTRL].TxBufDesc.TxImmedLen = MAX_IMMED_LEN;
TxDesc[CTRL].TxBufDesc.TxImmedPtr =
(BYTE far *) _fcalloc (MAX_IMMED_LEN, sizeof (BYTE));
TxDesc[CTRL].TxBufDesc.TxDataCnt = 0;
TxDesc[CTRL].TxBufDesc.TxDataBlk[0].TxPtrType = 0;
TxDesc[CTRL].TxBufDesc.TxDataBlk[0].TxRsvdByte = 0;
TxDesc[CTRL].TxBufDesc.TxDataBlk[0].TxDataPtr = NULL;
offset = 0;
if (TokenRing)
{
TxDesc[CTRL].TxBufDesc.TxImmedPtr[offset++] = 0x10;
TxDesc[CTRL].TxBufDesc.TxImmedPtr[offset++] = 0x40;
}
TxDesc[CTRL].pDest = (TxDesc[CTRL].TxBufDesc.TxImmedPtr + offset);
TxDesc[CTRL].pSrc = (TxDesc[CTRL].TxBufDesc.TxImmedPtr + offset +
MACMSC.MscStnAdrSz);
TxDesc[CTRL].pData = (TxDesc[CTRL].TxBufDesc.TxImmedPtr +
WedgeCommon->HeaderLen);
strcpy ((char *) TxDesc[CTRL].pData, CTRLID);
TxDesc[CTRL].pOpCode = TxDesc[CTRL].pData + strlen (CTRLID);
}
int TTUseGDT ()
{
// USEGDT
if (DOSVersion == OS2)
WedgeCommon->UseGDT = (WedgeCommon->UseGDT) ? FALSE : TRUE;
if (WedgeCommon->UseGDT)
aprintf (0, 77, 0x74, "G");
else
aprintf (0, 77, 0x70, " ");
return SUCCESS;
}
int TTSetTxBuffSize ()
{
// TXSIZE *<Size>
// if no parameters given, then display buffer sizes
char *token;
WORD i, BlkCnt, BlkSize, TotalSize = 0;
token = strtok (NULL, "\n\t ");
if (token)
{
// free up the previous buffers
_ffree ((void far *) TxDesc[TRAN].TxBufDesc.TxImmedPtr);
for (i=0; i<TxDesc[TRAN].TxBufDesc.TxDataCnt; ++i)
_ffree ((void far *) TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxDataPtr);
// reset the block count
BlkCnt = TxDesc[TRAN].TxBufDesc.TxDataCnt = 0;
// get the immediate buffer size
if ((TxDesc[TRAN].TxBufDesc.TxImmedLen = (int) GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
/* attempt to allocate each buffer (Immediate and Data) */
/* in a different segment */
// allocate the immediate buffer
TxDesc[TRAN].TxBufDesc.TxImmedPtr =
(BYTE far *) calloc (TxDesc[TRAN].TxBufDesc.TxImmedLen, sizeof (BYTE));
if (!TxDesc[TRAN].TxBufDesc.TxImmedPtr)
TxDesc[TRAN].TxBufDesc.TxImmedPtr =
(BYTE far *) calloc (MAX_IMMED_LEN, sizeof (BYTE));
// loop to get the data block sizes and allocate the buffers
while ((token = strtok (NULL, "\n\t ")) != NULL)
{
if ((BlkSize = (WORD) GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
TxDesc[TRAN].TxBufDesc.TxDataBlk[BlkCnt].TxDataLen = BlkSize;
TxDesc[TRAN].TxBufDesc.TxDataBlk[BlkCnt].TxDataPtr =
(BYTE far *) _fcalloc ((USHORT) HALFSEGPLUS, sizeof (BYTE));
if (!TxDesc[TRAN].TxBufDesc.TxDataBlk[BlkCnt].TxDataPtr)
TxDesc[TRAN].TxBufDesc.TxDataBlk[BlkCnt].TxDataPtr =
(BYTE far *) _fcalloc (BlkSize, sizeof (BYTE));
BlkCnt = ++TxDesc[TRAN].TxBufDesc.TxDataCnt;
}
}
else
{
PrintMsg (0, "Immediate Length: %d", TxDesc[TRAN].TxBufDesc.TxImmedLen);
for (i=0; i<TxDesc[TRAN].TxBufDesc.TxDataCnt; ++i)
PrintMsg (0, "Tx Data Block %d Length: %d",
i, TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxDataLen);
}
return SUCCESS;
}
int TTEditBuffer ()
{
// EDITBUF {I | # | R} <Data>
char *token, *s;
int i = 0, j, bufno, cnt, max;
USHORT data;
token = strtok (NULL, "\n\t ");
if (!token) return TT_INVALID_PARAMETER;
if (*token == 'I')
{
while ((token = strtok (NULL, "\n\t ")) != NULL)
{
if ((s = strstr (token, "*")))
{
*s++ = '\0';
if (sscanf (token, "%d", &cnt) != 1)
return TT_INVALID_PARAMETER;
if (sscanf (s, "%02X", &data) != 1)
return TT_INVALID_PARAMETER;
max = (cnt > TxDesc[TRAN].TxBufDesc.TxImmedLen) ?
TxDesc[TRAN].TxBufDesc.TxImmedLen : cnt;
for (j=0; j<max; ++j)
TxDesc[TRAN].TxBufDesc.TxImmedPtr[i++] = data;
}
else
{
if (sscanf (token, "%02X", &data) != 1)
return TT_INVALID_PARAMETER;
TxDesc[TRAN].TxBufDesc.TxImmedPtr[i++] = data;
}
}
}
else if (*token == 'R')
{
return (TTEditTMBuffer ());
}
else if (token)
{
if (sscanf (token, "%d", &bufno) != 1)
return TT_INVALID_PARAMETER;
if (bufno < TxDesc[TRAN].TxBufDesc.TxDataCnt)
while ((token = strtok (NULL, "\n\t ")) != NULL &&
i < TxDesc[TRAN].TxBufDesc.TxDataBlk[bufno].TxDataLen)
{
if ((s = strstr (token, "*")))
{
*s++ = '\0';
if (sscanf (token, "%d", &cnt) != 1)
return TT_INVALID_PARAMETER;
if (sscanf (s, "%02X", &data) != 1)
return TT_INVALID_PARAMETER;
max = (cnt > TxDesc[TRAN].TxBufDesc.TxDataBlk[bufno].TxDataLen) ?
TxDesc[TRAN].TxBufDesc.TxDataBlk[bufno].TxDataLen : cnt;
for (j=0; j<max; ++j)
TxDesc[TRAN].TxBufDesc.TxDataBlk[bufno].TxDataPtr[i++] = data;
}
else
{
if (sscanf (token, "%02X", &data) != 1)
return TT_INVALID_PARAMETER;
TxDesc[TRAN].TxBufDesc.TxDataBlk[bufno].TxDataPtr[i++] = data;
}
}
else
return TT_INVALID_PARAMETER;
} /* endif */
return SUCCESS;
}
int TTDispXmitBuf ()
{
// TXBUF
char *token;
int i;
BOOLEAN pause = FALSE;
PrintMsg (0, "Immediate Buffer");
if ((token = strtok (NULL, "\n\t ")))
if (*token == 'P') pause = TRUE;
hexprint (TxDesc[TRAN].TxBufDesc.TxImmedPtr,
TxDesc[TRAN].TxBufDesc.TxImmedLen, pause);
for (i=0; i<TxDesc[TRAN].TxBufDesc.TxDataCnt; ++i)
{
PrintMsg (0, "Data Buffer %d", i);
hexprint (TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxDataPtr,
TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxDataLen, pause);
}
return SUCCESS;
}
int TTXmit ()
{
// TRAN [<Return>]
char *RetCode;
int i, ExpRC;
TXDESC TempTxDesc; // saves the GDT pointers
IOCTLDATA IOData;
IOCTLDATA far *IODataPtr = &IOData;
if (Debug)
{
RetCode = strtok (NULL, "\n\t ");
if (!RetCode) return TT_INVALID_PARAMETER;
if ((ExpRC = GetRCInt (RetCode)) < 0)
return TT_INVALID_PARAMETER;
TMSetResult (ExpRC);
}
// Put the Current Station Address in the frame header
_fmemcpy ((void far *) TxDesc[TRAN].pSrc,
(void far *) MACMSC.MscCurrStnAdr, MACMSC.MscStnAdrSz);
// save GDT pointers
TempTxDesc = TxDesc[TRAN];
TxChain.ReqHandle = ++ReqHandle;
for (i=0; i<TxDesc[TRAN].TxBufDesc.TxDataCnt; ++i)
{
TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxPtrType = GDT_ADDR;
if (!WedgeCommon->UseGDT)
{
TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxPtrType = PHYS_ADDR;
IOData.ReqCode = VIRT_TO_PHYS;
IOData.Length = 0;
IOData.SrcDataPtr =
(void far *) TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxDataPtr;
IOData.DestDataPtr = NULL;
GenIoctl ((void far *) IODataPtr, hWedge);
TxDesc[TRAN].TxBufDesc.TxDataBlk[i].TxDataPtr = IOData.SrcDataPtr;
}
}
TxChain.TxBuffDescPtr = (void far *) &TxDesc[TRAN].TxBufDesc;
IOData.ReqCode = MACCMD;
IOData.Length = TRANSMITCHAIN;
IOData.SrcDataPtr = (void far *) &TxChain;
IOData.DestDataPtr = NULL;
GenIoctl ((void far *) IODataPtr, hWedge);
LastStatus = IOData.ReqCode;
// restore GDT pointers
TxDesc[TRAN] = TempTxDesc;
PrintMsg (0, "TransmitChain: %s", RetStr[LastStatus]);
return SUCCESS;
}
int TTMultipleXmit ()
{
// MULTRAN [Cnt] [<Min> <Max>] [<Type> [<NetAddr>]]
char *token;
int i, parmcnt = 0,
Min = WedgeCommon->HeaderLen,
Max = MACMSC.MscMaxFrame,
MaxDataLen = MACMSC.MscMaxFrame - WedgeCommon->HeaderLen,
DataLen,
Type = BROADCAST,
tempaddr,
Inc = 0;
ULONG Cnt = 50L;
IOCTLDATA IOData, PhysIOData;
IOCTLDATA far *IODataPtr = &IOData, *PhysIODataPtr = &PhysIOData;
// get the number of frames to transmit
if ((token = strtok (NULL, "\n\t ")))
{
if ((Cnt = GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
if (!Cnt) Cnt = 1;
++parmcnt;
}
// get the minimum length of the frames (optional)
if ((token = strtok (NULL, "\n\t ")))
{
if ((Min = (int) GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
++parmcnt;
}
if (Min > MACMSC.MscMaxFrame)
Min = MACMSC.MscMaxFrame;
else if (Min < WedgeCommon->HeaderLen)
Min = WedgeCommon->HeaderLen;
// get the maximum length of the frames (optional)
if ((token = strtok (NULL, "\n\t ")))
{
if ((Max = (int) GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
if (Max > MACMSC.MscMaxFrame)
Max = MACMSC.MscMaxFrame;
if (Max < Min) Max = Min;
++parmcnt;
}
if (parmcnt != 2 && Min != Max)
{
if (Cnt >= 2)
{
Inc = (Max - Min) / (Cnt - 1);
if (!Inc) Inc = 1;
}
else Min = MAX_IMMED_LEN;
}
// get the type of the frame (optional)
if ((token = strtok (NULL, "\n\t ")))
{
if ((Type = (int) GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
}
switch (Type)
{
case BROADCAST:
_fmemcpy ((void far *) TxDesc[MTRAN].pDest,
(void far *) BroadcastAddr, MACMSC.MscStnAdrSz);
break;
case DIRECTED:
case DIRECTED_TO_WKSTA:
// get the destination address of the frame (required at this point)
for (i=0; i<MACMSC.MscStnAdrSz; ++i)
{
if (!(token = strtok (NULL, "\n\t ")))
return TT_INVALID_PARAMETER;
if ((sscanf (token, "%02X", &tempaddr) != 1))
return TT_INVALID_PARAMETER;
TxDesc[MTRAN].pDest[i] = (BYTE) tempaddr;
} /* endfor */
break;
case DIRECTED_TO_SERVER:
_fmemcpy ((void far *) TxDesc[MTRAN].pDest,
(void far *) WedgeCommon->ServerAddr, MACMSC.MscStnAdrSz);
break;
} /* endswitch */
// put in the Source Address
_fmemcpy ((void far *) TxDesc[MTRAN].pSrc,
(void far *) MACMSC.MscCurrStnAdr, MACMSC.MscStnAdrSz);
// put frame length in the frame data
DataLen = Min - WedgeCommon->HeaderLen;
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataLen = DataLen;
*(WORD *) TxDesc[MTRAN].pLen = DataLen;
// determine where the TxDataPtr should be
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr =
&TxDesc[MTRAN].TxBufDesc.TxImmedPtr[MACMSC.MscMaxFrame - DataLen];
TxChain.ReqHandle = 0;
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxPtrType = GDT_ADDR;
if (!WedgeCommon->UseGDT)
{
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxPtrType = PHYS_ADDR;
// get the MTRAN Data Block physical address
PhysIOData.ReqCode = VIRT_TO_PHYS;
PhysIOData.SrcDataPtr =
(void far *) TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr;
GenIoctl ((void far *) PhysIODataPtr, hWedge);
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr = PhysIOData.SrcDataPtr;
}
TxChain.TxBuffDescPtr = (void far *) &TxDesc[MTRAN].TxBufDesc;
IOData.ReqCode = MACCMD;
IOData.Length = TRANSMITCHAIN;
IOData.SrcDataPtr = (void far *) &TxChain;
IOData.DestDataPtr = NULL;
//hexprint (TxDesc[MTRAN].TxBufDesc.TxImmedPtr, MAX_IMMED_LEN, 0);
//getch ();
for (i=0; i<Cnt - 1; ++i)
{
// Transmit the frame
GenIoctl ((void far *) IODataPtr, hWedge);
PrintMsg (0, "TransmitChain: %s", RetStr[IOData.ReqCode]);
// check for indications (like ReceiveLookahead or ReceiveChain)
CheckIndications ();
// increment the DataLen if necessary
if (Cnt > 1 && i == Cnt - 2)
{
// last frame should be Max FrameSize or Max parameter
if (parmcnt < 2)
DataLen = MaxDataLen;
else if (parmcnt == 3)
DataLen = Max - WedgeCommon->HeaderLen;
}
else
DataLen += Inc;
// bounds check
if (DataLen > MaxDataLen) DataLen = MaxDataLen;
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataLen = DataLen;
// put the DataLen in as the first word of data
*(WORD *) TxDesc[MTRAN].pLen = DataLen;
// determine where the TxDataPtr should be
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr =
&TxDesc[MTRAN].TxBufDesc.TxImmedPtr[MACMSC.MscMaxFrame - DataLen];
if (!WedgeCommon->UseGDT)
{
// get the MTRAN Data Block physical address -- again
PhysIOData.ReqCode = VIRT_TO_PHYS;
PhysIOData.SrcDataPtr = TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr;
GenIoctl ((void far *) PhysIODataPtr, hWedge);
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr = PhysIOData.SrcDataPtr;
}
// reset the Request Code because it came back as the Status
IOData.ReqCode = MACCMD;
} /* endfor */
// Transmit the last frame or the only frame
GenIoctl ((void far *) IODataPtr, hWedge);
PrintMsg (0, "TransmitChain: %s", RetStr[IOData.ReqCode]);
return SUCCESS;
}
int TTIndicationsOff ()
{
// INDICOFF [<Return>]
IOCTLDATA IOData;
IOCTLDATA far *IODataPtr = &IOData;
if (GetRetCodes ()) return TT_INVALID_PARAMETER;
IOData.ReqCode = MACCMD;
IOData.Length = INDICATIONOFF;
IOData.SrcDataPtr = NULL;
IOData.DestDataPtr = NULL;
GenIoctl ((void far *) IODataPtr, hWedge);
LastStatus = IOData.ReqCode;
PrintMsg (0, "Indications Off: %s", RetStr[LastStatus]);
return SUCCESS;
}
int TTIndicationsOn ()
{
// INDICON [<Return>]
IOCTLDATA IOData;
IOCTLDATA far *IODataPtr = &IOData;
if (GetRetCodes ()) return TT_INVALID_PARAMETER;
IOData.ReqCode = MACCMD;
IOData.Length = INDICATIONON;
IOData.SrcDataPtr = NULL;
IOData.DestDataPtr = NULL;
GenIoctl ((void far *) IODataPtr, hWedge);
LastStatus = IOData.ReqCode;
PrintMsg (0, "Indications On: %s", RetStr[LastStatus]);
return SUCCESS;
}
USHORT SendControlFrame (int CFCode)
{
char *token;
int i;
BYTE far *data;
WORD tempaddr;
WORD Type = BROADCAST;
ULONG Cnt, Min, Max;
IOCTLDATA IOData;
IOCTLDATA far *IODataPtr = &IOData;
switch (CFCode)
{
case CCWKSTA:
/* send a broadcast frame out to find a server */
// put in the broadcast address
_fmemcpy ((void far *) TxDesc[CTRL].pDest,
(void far *) BroadcastAddr,
MACMSC.MscStnAdrSz);
// put in the source address
_fmemcpy ((void far *) TxDesc[CTRL].pSrc,
(void far *) MACMSC.MscCurrStnAdr,
MACMSC.MscStnAdrSz);
// put in the Control Code
*(WORD *) TxDesc[CTRL].pOpCode = CFCode;
// no data required
break;
case CCSERVER:
// send a directed frame to a workstation
// put in the workstation address
_fmemcpy ((void far *) TxDesc[CTRL].pDest,
(void far *) ControlFrame.pSrc,
MACMSC.MscStnAdrSz);
// put in the source address
_fmemcpy ((void far *) TxDesc[CTRL].pSrc,
(void far *) MACMSC.MscCurrStnAdr,
MACMSC.MscStnAdrSz);
// put in the Control Code
*(WORD *) TxDesc[CTRL].pOpCode = CFCode;
// no data required
PrintMsg (RED, "CCSERVER sent");
hexprint (TxDesc[CTRL].pDest, 64, 0);
break;
case CCSTRESS:
// send a broadcast frame to tell workstations to start stressing
case CCSRVSTOP:
// send a broadcast frame to tell workstations that server has
// quit the stress test
// put in the broadcast address
_fmemcpy ((void far *) TxDesc[CTRL].pDest,
(void far *) BroadcastAddr,
MACMSC.MscStnAdrSz);
// put in the source address
_fmemcpy ((void far *) TxDesc[CTRL].pSrc,
(void far *) MACMSC.MscCurrStnAdr,
MACMSC.MscStnAdrSz);
// put in the Control Code
data = (BYTE far *) TxDesc[CTRL].pOpCode;
*(WORD *) data = (WORD) CFCode;
if (CFCode == CCSTRESS)
{
data += sizeof (WORD);
// put in the the stress parameters
PutStressParms (data);
}
if (CFCode == CCSTRESS)
PrintMsg (RED, "CCSTRESS sent");
else
PrintMsg (RED, "CCSRVSTOP sent");
hexprint (TxDesc[CTRL].pDest, 30, 0);
break;
case CCXMIT:
// send a directed frame to the server telling him
// to do a MULTRAN with the current command parameters
// put in the server address
_fmemcpy ((void far *) TxDesc[CTRL].pDest,
(void far *) ControlFrame.pSrc,
MACMSC.MscStnAdrSz);
// put in the source address
_fmemcpy ((void far *) TxDesc[CTRL].pSrc,
(void far *) MACMSC.MscCurrStnAdr,
MACMSC.MscStnAdrSz);
// put in the Control Code
data = (BYTE far *) TxDesc[CTRL].pOpCode;
*(WORD *) data = (WORD) CFCode;
data += sizeof (WORD);
/* parse the data out */
// get the count (number of frames to transmit - required)
if (!(token = strtok (NULL, "\n\t ")))
return TT_INVALID_PARAMETER;
if ((Cnt = GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
*(DWORD *) data = Cnt;
data += sizeof (DWORD);
// get the Min and Max parameters (required)
if (!(token = strtok (NULL, "\n\t ")))
return TT_INVALID_PARAMETER;
if ((Min = GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
*(DWORD *) data = Min;
data += sizeof (DWORD);
if (!(token = strtok (NULL, "\n\t ")))
return TT_INVALID_PARAMETER;
if ((Max = GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
*(DWORD *) data = Max;
data += sizeof (DWORD);
// get the frame type (optional)
if ((token = strtok (NULL, "\n\t ")))
{
if ((Type = (WORD) GetNumericParm (token)) < 0)
return TT_INVALID_PARAMETER;
}
*(WORD *) data = Type;
data += sizeof (WORD);
switch (Type)
{
case BROADCAST:
case DIRECTED_TO_WKSTA:
case DIRECTED_TO_SERVER:
break;
case DIRECTED:
// get the destination address of the frame (required at this point)
for (i=0; i<MACMSC.MscStnAdrSz; ++i)
{
if (!(token = strtok (NULL, "\n\t ")))
return TT_INVALID_PARAMETER;
if ((sscanf (token, "%02X", &tempaddr) != 1))
return TT_INVALID_PARAMETER;
*(BYTE *) data++ = (BYTE) tempaddr;
} /* endfor */
break;
default:
return TT_INVALID_PARAMETER;
break;
} /* endswitch */
break;
case CCDELWKSTA:
case CCENDSTRESS:
case CCQUERYACK:
// put in the server address
_fmemcpy ((void far *) TxDesc[CTRL].pDest,
(void far *) WedgeCommon->ServerAddr,
MACMSC.MscStnAdrSz);
// put in the source address
_fmemcpy ((void far *) TxDesc[CTRL].pSrc,
(void far *) MACMSC.MscCurrStnAdr,
MACMSC.MscStnAdrSz);
// put in the Control Code
*(WORD far *) TxDesc[CTRL].pOpCode = (WORD) CFCode;
// no data required
if (CFCode == CCDELWKSTA)
PrintMsg (RED, "CCDELWKSTA sent");
else if (CFCode == CCENDSTRESS)
PrintMsg (RED, "CCENDSTRESS sent");
else
PrintMsg (RED, "CCQUERYACK sent");
hexprint (TxDesc[CTRL].pDest, 64, 0);
break;
case CCENDSTRESSACK:
case CCQUERYWKSTA:
// put in the workstation's address
_fmemcpy ((void far *) TxDesc[CTRL].pDest,
(void far *) ControlFrame.pSrc,
MACMSC.MscStnAdrSz);
// put in the source address
_fmemcpy ((void far *) TxDesc[CTRL].pSrc,
(void far *) MACMSC.MscCurrStnAdr,
MACMSC.MscStnAdrSz);
// put in the Control Code
*(WORD far *) TxDesc[CTRL].pOpCode = (WORD) CFCode;
// no data required
if (CFCode == CCENDSTRESSACK)
PrintMsg (RED, "CCENDSTRESSACK sent");
else
PrintMsg (RED, "CCQUERYWKSTA sent");
hexprint (TxDesc[CTRL].pDest, 64, 0);
break;
} /* endswitch */
// do the Ioctl
TxChain.TxBuffDescPtr = (void far *) &TxDesc[CTRL].TxBufDesc;
IOData.ReqCode = MACCMD;
IOData.Length = TRANSMITCHAIN;
IOData.SrcDataPtr = (void far *) &TxChain;
IOData.DestDataPtr = NULL;
GenIoctl ((void far *) IODataPtr, hWedge);
LastStatus = IOData.ReqCode;
return SUCCESS;
}
void PrimEcho ()
{
int BlkSize;
IOCTLDATA IOData;
IOCTLDATA far *IODataPtr = &IOData;
TXDESC TempTxDesc; // saves the GDT pointers
// save GDT pointers
TempTxDesc = TxDesc[MTRAN];
/*** set up the MTRAN Buffer Descriptor ***/
// copy received data
_fmemcpy ((void far *) TxDesc[MTRAN].TxBufDesc.TxImmedPtr,
(void far *) WedgeCommon->RcvData, LastFrameSize);
// set the immediate length
TxDesc[MTRAN].TxBufDesc.TxImmedLen = MAX_IMMED_LEN;
// set the data block length
BlkSize = LastFrameSize - MAX_IMMED_LEN;
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataLen =
(BlkSize > 0) ? BlkSize : 0;
// set the data block ptr
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr =
TxDesc[MTRAN].TxBufDesc.TxImmedPtr + (LastFrameSize - MAX_IMMED_LEN);
// replace destination address with source address
_fmemcpy ((void far *) TxDesc[MTRAN].pDest,
(void far *) TxDesc[MTRAN].pSrc, MACMSC.MscStnAdrSz);
// put the Current Station Address in as the source address
_fmemcpy ((void far *) TxDesc[MTRAN].pSrc,
(void far *) MACMSC.MscCurrStnAdr, MACMSC.MscStnAdrSz);
TxChain.ReqHandle = ++ReqHandle;
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxPtrType = GDT_ADDR;
if (!WedgeCommon->UseGDT)
{
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxPtrType = PHYS_ADDR;
IOData.ReqCode = VIRT_TO_PHYS;
IOData.Length = 0;
IOData.SrcDataPtr =
(void far *) TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr;
IOData.DestDataPtr = NULL;
GenIoctl ((void far *) IODataPtr, hWedge);
TxDesc[MTRAN].TxBufDesc.TxDataBlk[0].TxDataPtr = IOData.SrcDataPtr;
}
TxChain.TxBuffDescPtr = (void far *) &TxDesc[MTRAN].TxBufDesc;
IOData.ReqCode = MACCMD;
IOData.Length = TRANSMITCHAIN;
IOData.SrcDataPtr = (void far *) &TxChain;
IOData.DestDataPtr = NULL;
GenIoctl ((void far *) IODataPtr, hWedge);
LastStatus = IOData.ReqCode;
// restore GDT pointers
TxDesc[MTRAN] = TempTxDesc;
PrintMsg (0, "TransmitChain: %s", RetStr[LastStatus]);
// restore MTRAN's normal immediate length
TxDesc[MTRAN].TxBufDesc.TxImmedLen = WedgeCommon->HeaderLen;
// restore the Broadcast Address as the Destination for MTRAN
_fmemcpy ((void far *) TxDesc[MTRAN].pDest,
(void far *) BroadcastAddr, 6);
}