![]() |
VR-Link API Documentation for HLA 1.3
|
This is a simple program that prints all received PDUs.
/******************************************************************************* ** Copyright (c) 1992-2010 VT MAK ** All rights reserved. *******************************************************************************/ #if DtDIS #include <vlutil/vlTime.h> #include <vlutil/vlInetUdpSocket.h> #include <vlutil/vlInetDevice.h> #include <vlutil/vlProcessControl.h> #include <vlutil/vlKeyboard.h> #include <vlutil/vlInetInterfaceUtils.h> #include <vlutil/vlInetPlatformUtils.h> #include <cmdLine/cmdLine.h> #include <vl/exerciseConn.h> #include <vl/disPduFactory.h> #include <vl/unknownPdu.h> #include <vlutil/vlPrintUtil.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> 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 DT_VXWORKS_APP(netdump) #endif int main( int argc, char** argv ) { 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(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 DtInetEndpoint endpoint; endpoint.setProtocol(DtInetProtocol_UDP); endpoint.setPort(disPort); if (destAddrString.isSet()) { // The user set a destination address, use it. endpoint.setAddress(destAddrString.getValue()); } else { // Use the primary broadcast address DtInetAddr* bcastAddr = DtInetUtils::getPrimaryBroadcastAddress(useIpv6); if (bcastAddr) { endpoint.setAddress(*bcastAddr); } else { DtFatalError("Cannot obtain primary broadcast address.\n"); } DtDELETE(bcastAddr); } 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; } } DtInetUdpSocket* skt = new DtInetUdpSocket(endpoint, 0, netDeviceToUse); skt->setNonBlockingOption(true); if (skt->isOk()) { DtWarn << "Netdump socket OK to: " << skt->destination().toDtString() << std::endl; } else { DtFatalError("Cannot construct a socket to: %s\n", skt->destination().toDtString().c_str()); } 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) { skt->joinMulticastGroup(DtInetAddr(*pos)); } DtDisPduFactory fact; 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; if ( size != pktSize ) { 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