VR-Link API Documentation for DIS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DIS Netdump Example

This is a simple program that prints all received PDUs.


/****************************************************************************
* Copyright (c) 2014 VT MAK
* All rights reserved.
****************************************************************************/
#if DtDIS
#include <vlutil/vlTime.h>
#include <vl/unknownPdu.h>
#include <vcPdu.h>
#include <signal.h>
#include <stdio.h>
#include <iostream>
#include <vector>
// Returns -1 if user entered q or Q, 0 otherwise
int keybrdTick( void );
// Reads and prints a PDU. Returns 0 if there were none to be read.
int readAndProcess( DtInetUdpSocket* skt );
// Globals
char* vb = 0;
char* clearScreen = (char *)"";
int numBetweenStdinChecks = 100;
#if defined(_WIN32) || defined(__solaris__)
unsigned int defaultReceiveBufferSize(DtInetUtils::getMaxPacketBufferSize());
#else
unsigned int defaultReceiveBufferSize(UINT_MAX);
#endif
DtCmdLine::ValueArg<DtString> destAddrString("A","destAddrString", "DIS Destination Address String", false, "0.0.0.0", "IP Address");
DtCmdLine::ValueArg<DtString> netmaskString("N","netmaskString", "DIS Net Mask Address String", false, "0.0.0.0", "IP Address");
DtCmdLine::ValueArg<DtString> deviceAddrString("","deviceAddress", "DIS Device Address String", false, "0.0.0.0", "IP Address");
DtCmdLine::ValueArg<int> disPort("P", "disPort", "DIS Port", false, 3000, "integer");
DtCmdLine::SwitchArg verbose("", "verbose", "Enable Verbose Output", false);
DtCmdLine::SwitchArg useIpv6("", "useIpv6", "Use IPv6", false);
DtCmdLine::SwitchArg errorChecking("", "errorChecking", "Enable Error Checking", false);
DtCmdLine::SwitchArg clearScreenFlag("c", "clrScreen", "Clear Screen Between PDUs", false);
DtCmdLine::ValueArg<int> receiveBufferSize("", "receiveBufferSize", "Receive Buffer Size", false, defaultReceiveBufferSize, "integer");
DtCmdLine::MultiArg<DtString> mcastAddrs("S", "mcastAddr", "Multicast Address", false, "IP Address");
DtCmdLine::SwitchArg printRaw("r", "raw", "Print Raw Data", false);
DtPduFactory* pduFactory;
DtClock* vrClock = new DtClock();
#if VXWORKS
#define main realMain
#endif
int main( int argc, char* argv[] )
{
// Used for error handling
DtINIT_MINIDUMPER( "DIS-Netdump" );
signal( SIGFPE, SIG_IGN );
DtInfo << "Using VR-Link version " << VR_LINK_VERSION_STRING << std::endl;
DtInfo << "Built on " << DtOperatingSystem() << " with " << DtCompiler() << " - " <<
#if DT_HAVE_64BIT_LONGS
"64bit"
#else
"32bit"
#endif
<< std::endl;
#ifndef _GT_
/* this increases speed of output, since dumpPdu will fflush */
setvbuf( stdout, NULL, _IOFBF, BUFSIZ );
#endif
DtCmdLine::CmdLine cmdLine("DIS Netdump", ' ', DtExerciseConn::vrlinkVersion().c_str());
cmdLine.add(destAddrString);
cmdLine.add(netmaskString);
cmdLine.add(deviceAddrString);
cmdLine.add(disPort);
cmdLine.add(verbose);
cmdLine.add(useIpv6);
cmdLine.add(errorChecking);
cmdLine.add(receiveBufferSize);
cmdLine.add(clearScreenFlag);
cmdLine.add(mcastAddrs);
cmdLine.add(printRaw);
cmdLine.parse(argc, argv);
if (clearScreenFlag)
{
clearScreen = (char *)"\033[H\033[2J";
}
// Initialize the socket
DtInetDevice* netDeviceToUse = 0;
DtInetDevice netDevice(DtInetAddr(deviceAddrString.getValue()));
if (deviceAddrString.isSet())
{
if (netDevice.isOk())
{
netDeviceToUse = &netDevice;
}
else
{
DtWarn << "Invalid device address: \"" << deviceAddrString.getValue() << "\" Using default." << std::endl;
}
}
DtInetEndpoint endpoint;
endpoint.setPort(disPort);
DtInetAddr destAddr(destAddrString.getValue());
if (netmaskString.isSet())
{
destAddr = DtInetAddr(destAddrString.getValue(), netmaskString.getValue());
}
if (destAddrString.isSet())
{
// The user set a destination address, use it.
endpoint.setAddress(destAddr);
}
else
{
// Use the primary broadcast address
if (bcastAddr)
{
endpoint.setAddress(*bcastAddr);
}
else
{
DtFatalError("Cannot obtain primary broadcast address.\n");
}
DtDELETE(bcastAddr);
}
DtInetUdpSocket* skt = new DtDisSocket(endpoint, 0, netDeviceToUse);
if (skt->isOk())
{
DtWarn << "Netdump socket OK to: " << skt->destination().toDtString() << std::endl;
}
else
{
DtFatalError("Cannot construct a socket to: %s\n",
}
if (receiveBufferSize.isSet())
{
// User changed the receive buffer size.
if (receiveBufferSize <= 0)
{
DtWarn << "Invalid receive buffer size: " << receiveBufferSize.getValue() << " must be > 0." << std::endl;
DtWarn << "Using default: " << skt->getReceiveBufferSize() << std::endl;
}
else
{
skt->setReceiveBufferSize(receiveBufferSize);
}
}
std::vector <DtString>::const_iterator pos = mcastAddrs.getValue().begin();
for (; pos != mcastAddrs.getValue().end(); ++pos)
{
}
pduFactory = &fact;
pduFactory->DtADD_PDU_CREATOR(ViewControl);
fflush( stdout );
if ( verbose )
{
vb =(char *)"************************************************************\n";
}
else
{
vb = (char *)"";
}
int forever = 1; // to keep cfront quiet
while( forever )
{
// Keep reading and processing as long as there is stuff to read.
// Check for keyboard input every numBetweenStdinChecks reads.
int numBeforeStdinCheck = 0;
do
{
if ( numBeforeStdinCheck == 0 )
{
numBeforeStdinCheck = numBetweenStdinChecks;
if ( keybrdTick() == -1 )
{
return 0;
}
}
else
{
--numBeforeStdinCheck;
}
} while( readAndProcess( skt ) );
}
return 0;
}
int readAndProcess( DtInetUdpSocket* skt )
{
static int n = 1;
char packet[15000];
DtInetEndpoint fromAddress;
DtInetSockRcvStatus status = skt->recvFrom((caddr_t)packet, 15000, fromAddress);
int size = status;
if ( !status )
{
return 0;
}
int pktSize = ( (DtNetPduHeader*)packet )->DtLength;
unsigned int pktVersion = ( (DtNetPduHeader*)packet )->version;
bool isCoupling = ((DtU8)( (DtNetPduHeader*)packet )->pduStatus) & 0x8;
if ( size != pktSize && pktVersion >= 7 && !isCoupling)
{
std::cout << "#### WARNING: Size mismatch: Received("<< size
<<"), DIS Header(" << pktSize << ") ####\n";
if ( errorChecking )
{
std::cout << " Will not attempt to print this PDU."<< std::endl;
return 1;
}
}
DtPdu* pdu;
int version = ( (DtNetPduHeader*)packet )->version;
if ( version >= DtProtocolVersionToRecvMin &&
version <= DtProtocolVersionToRecvMax )
{
pdu = pduFactory->createPdu( (DtNetPacket*)packet, (DtBufferPtr)packet );
}
else
{
pdu = new DtUnknownPdu( (DtNetPacket*)packet, (DtBufferPtr)packet );
}
if ( pdu )
{
if (printRaw)
{
printf( "%s%s******** PDU #%-6d \t\t %13.3f secs ********\n%s",
clearScreen, vb, n++, vrClock->elapsedRealTime(), vb );
pdu->printHeader();
int pduSize = pdu->length();
for (int k = 0; k < pduSize; k += 4)
{
printf("%04x\t%08x\n", k, *(DtU32 *)(pdu->netRep() + k));
}
printf("\n");
fflush(stdout);
}
else
{
printf( "%s%s******** PDU #%-6d \t\t %13.3f secs ********\n%s",
clearScreen, vb, n++, vrClock->elapsedRealTime(), vb );
printf("SourceInetAddr:\t %s\n", fromAddress.address().toDtString().c_str());
pdu->print();
printf( "\n" );
delete pdu;
fflush( stdout );
}
}
return 1;
}
int keybrdTick()
{
char* keyPtr = DtPollBlockingInputLine();
if ( !keyPtr )
{
return 0; // no input
}
switch( *keyPtr )
{
case 'q':
case 'Q':
{
return -1;
}
default:
{
std::cout << "Unrecognized command key <" << *keyPtr << ">"
<< std::endl;
break;
}
}
return 0;
}
#endif


Document ID: Generated on Wed Jan 7 13:31:29 EST 2015 from SVN revision 149162
Copyright © 2005-2014 VT MÄK. All Rights Reserved (www.mak.com)