wireshark/epan/dissectors/packet-dis-pdus.c

1592 lines
70 KiB
C

/* packet-dis-pdus.c
* Routines and definitions for DIS PDU parsing.
* Copyright 2005, Scientific Research Corporation
* Initial implementation by Jeremy Ouellette <jouellet@scires.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "packet-dis-pdus.h"
#include "packet-dis-fields.h"
#include "packet-dis-enums.h"
#define DIS_PDU_MAX_VARIABLE_PARAMETERS 16
#define DIS_PDU_MAX_VARIABLE_RECORDS 16
#define DIS_PDU_MAX_ELECTROMAGNETIC_EMISSION_SYSTEMS 16
#define DIS_PDU_MAX_SHAFTS 16
#define DIS_PDU_MAX_APAS 16
#define DIS_PDU_MAX_UA_EMITTER_SYSTEMS 16
#define DIS_PDU_MAX_UA_BEAMS 32
gint ettVariableParameters[DIS_PDU_MAX_VARIABLE_PARAMETERS];
gint ettVariableRecords[DIS_PDU_MAX_VARIABLE_RECORDS];
gint ettFixedData = -1;
gint ettVariableData = -1;
/* DIS Entity Information / Interaction PDUs
*/
DIS_ParserNode DIS_PARSER_ENTITY_STATE_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_FORCE_ID, "Force ID",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_ARTICULATION_PARAMS, "Number of Articulation Parameters",0,0,0,&numVariable },
{ DIS_FIELDTYPE_ENTITY_TYPE, "Entity Type",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_TYPE, "Alternative Entity Type",0,0,0,0 },
{ DIS_FIELDTYPE_LINEAR_VELOCITY, "Entity Linear Velocity",0,0,0,0 },
{ DIS_FIELDTYPE_LOCATION_WORLD, "Entity Location",0,0,0,0 },
{ DIS_FIELDTYPE_ORIENTATION, "Entity Orientation",0,0,0,0 },
{ DIS_FIELDTYPE_APPEARANCE, "Entity Appearance",0,0,0,0 },
{ DIS_FIELDTYPE_DEAD_RECKONING_PARAMS, "Dead Reckoning Parameters",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_MARKING, "Entity Marking",0,0,0,0 },
{ DIS_FIELDTYPE_CAPABILITIES, "Capabilities",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_PARAMETERS, "Variable Parameter",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* DIS Distributed Emission Regeneration PDUs
*/
DIS_ParserNode DIS_PARSER_ELECTROMAGNETIC_EMISSION_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Emitting Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "State Update Indicator",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_ELECTROMAGNETIC_EMISSION_SYSTEMS, "Number of Systems (N)",0,0,0,&numVariable },
{ DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM, "Emission System",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* DIS Underwater Acoustic PDUs
*/
DIS_ParserNode DIS_PARSER_UNDERWATER_ACOUSTIC_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Emitting Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "State Update Indicator",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_UINT16, "Passive Parameter Index", 0,0,0,0 }, /* !! enum !! */
{ DIS_FIELDTYPE_UINT8, "Propulsion Plant Configuration",0,0,0,0 }, /* !! enum !! */
{ DIS_FIELDTYPE_NUM_OF_SHAFTS, "Number of Shafts",0,0,0,&numShafts },
{ DIS_FIELDTYPE_NUM_OF_APAS, "Number of Additional Passive Activities (APA)",0,0,0,&numApas },
{ DIS_FIELDTYPE_NUM_OF_UA_EMITTER_SYSTEMS, "Number of UA Emitter Systems",0,0,0,&numUAEmitter },
{ DIS_FIELDTYPE_SHAFTS, "Shafts",0,0,0,0 },
{ DIS_FIELDTYPE_APA, "APAs",0,0,0,0 },
{ DIS_FIELDTYPE_UA_EMITTER_SYSTEMS, "Underwater Acoustic Emission System",0,0,0,0 },
{ DIS_FIELDTYPE_UA_BEAMS, "Beams",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* DIS Radio Communications protocol (RCP) family PDUs
*/
DIS_ParserNode DIS_PARSER_TRANSMITTER_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_RADIO_ID, "Radio ID",0,0,0,&radioID },
{ DIS_FIELDTYPE_RADIO_ENTITY_TYPE, "Radio Entity Type",0,0,0,0 },
{ DIS_FIELDTYPE_RADIO_TRANSMIT_STATE, "Radio Transmit State",0,0,0,&disRadioTransmitState },
{ DIS_FIELDTYPE_RADIO_INPUT_SOURCE, "Radio Input Source",0,0,0,0 },
{ DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_ANTENNA_LOCATION, "Antenna Location",0,0,0,0 },
{ DIS_FIELDTYPE_REL_ANTENNA_LOCATON, "Relative Antenna Location",0,0,0,0 },
{ DIS_FIELDTYPE_ANTENNA_PATTERN_TYPE, "Antenna Pattern Type",0,0,0,&disAntennaPattern },
{ DIS_FIELDTYPE_ANTENNA_PATTERN_LENGTH, "Antenna Pattern Length",0,0,0,0 },
{ DIS_FIELDTYPE_TRANSMIT_FREQUENCY, "Transmit Frequency",0,0,0,0 },
{ DIS_FIELDTYPE_FLOAT32, "Transmit Frequency Bandwidth",0,0,0,0 },
{ DIS_FIELDTYPE_FLOAT32, "Transmit Power",0,0,0,0 },
{ DIS_FIELDTYPE_MODULATION_TYPE, "Modulation Type",0,0,0,0 },
{ DIS_FIELDTYPE_CRYPTO_SYSTEM, "Crypto System",0,0,0,0 },
{ DIS_FIELDTYPE_CRYPTO_KEY_ID, "Crypto Key ID",0,0,0,0 },
{ DIS_FIELDTYPE_MODULATION_PARAMETER_LENGTH, "Modulation Parameter Length",0,0,0,&modulationParamLength },
{ DIS_FIELDTYPE_PAD24, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_MODULATION_PARAMETERS, "Modulation Parameters",0,0,0,0 },
/* need to finish decoding this PDU */
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_SIGNAL_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_RADIO_ID, "Radio ID",0,0,0,&radioID },
{ DIS_FIELDTYPE_ENCODING_SCHEME, "Encoding Scheme",0,0,0,&encodingScheme },
{ DIS_FIELDTYPE_TDL_TYPE, "TDL Type",0,0,0,0 },
{ DIS_FIELDTYPE_SAMPLE_RATE, "Sample Rate",0,0,0,0 },
{ DIS_FIELDTYPE_DATA_LENGTH, "Data Length",0,0,0,0 },
{ DIS_FIELDTYPE_NUMBER_OF_SAMPLES, "Number of Samples",0,0,0,&numSamples },
{ DIS_FIELDTYPE_RADIO_DATA, "Radio Data",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* DIS Warfare PDUs
*/
DIS_ParserNode DIS_PARSER_FIRE_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Firing Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Target Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Munition ID",0,0,0,0 },
{ DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0,0 },
{ DIS_FIELDTYPE_UINT32, "Fire Mission Index",0,0,0,0 },
{ DIS_FIELDTYPE_LOCATION_WORLD, "Location in World Coordinates",0,0,0,0 },
{ DIS_FIELDTYPE_BURST_DESCRIPTOR, "Burst Descriptor",0,0,0,0 },
{ DIS_FIELDTYPE_LINEAR_VELOCITY, "Velocity",0,0,0,0 },
{ DIS_FIELDTYPE_FLOAT32, "Range",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_DETONATION_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Firing Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Target Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Munition ID",0,0,0,0 },
{ DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0,0 },
{ DIS_FIELDTYPE_LINEAR_VELOCITY, "Velocity",0,0,0,0 },
{ DIS_FIELDTYPE_LOCATION_WORLD, "Location in World Coordinates",0,0,0,0 },
{ DIS_FIELDTYPE_BURST_DESCRIPTOR, "Burst Descriptor",0,0,0,0 },
{ DIS_FIELDTYPE_LOCATION_ENTITY, "Location in Entity Coordinates",0,0,0,0 },
{ DIS_FIELDTYPE_DETONATION_RESULT, "Detonation Result",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_ARTICULATION_PARAMS, "Number of Articulation Parameters",0,0,0,&numVariable },
{ DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_PARAMETERS, "Variable Parameter",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* DIS Simulation Management PDUs
*/
DIS_ParserNode DIS_PARSER_START_RESUME_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
{ DIS_FIELDTYPE_CLOCK_TIME, "Simulation Time",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_STOP_FREEZE_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
{ DIS_FIELDTYPE_REASON, "Reason",0,0,0,0 },
{ DIS_FIELDTYPE_FROZEN_BEHAVIOR, "Frozen Behavior",0,0,0,0 },
{ DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_ACKNOWLEDGE_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ACKNOWLEDGE_FLAG, "Acknowledge Flag",0,0,0,0 },
{ DIS_FIELDTYPE_RESPONSE_FLAG, "Response Flag",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_ACTION_REQUEST_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_ACTION_ID, "Action ID",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_ACTION_RESPONSE_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_STATUS, "Request Status",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_DATA_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_PAD32, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_DATA_QUERY_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_TIME_INTERVAL, "Time interval",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Datum Ids",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Datum Ids",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUM_IDS, "Fixed datum ids",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUM_IDS, "Variable datum ids",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_COMMENT_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_SIMAN_ENTITY_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* DIS Simulation Management with Reliability PDUs
*/
DIS_ParserNode DIS_PARSER_START_RESUME_R_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
{ DIS_FIELDTYPE_CLOCK_TIME, "Simulation Time",0,0,0,0 },
{ DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_STOP_FREEZE_R_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
{ DIS_FIELDTYPE_REASON, "Reason",0,0,0,0 },
{ DIS_FIELDTYPE_FROZEN_BEHAVIOR, "Frozen Behavior",0,0,0,0 },
{ DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_ACTION_REQUEST_R_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_ACTION_ID, "Action ID",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_DATA_R_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_DATA_QUERY_R_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_TIME_INTERVAL, "Time interval",0,0,0,0 },
{ DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Datum Ids",0,0,0,&numFixed },
{ DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Datum Ids",0,0,0,&numVariable },
{ DIS_FIELDTYPE_FIXED_DATUM_IDS, "Fixed datum ids",0,0,0,0 },
{ DIS_FIELDTYPE_VARIABLE_DATUM_IDS, "Variable datum ids",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_SIMAN_ENTITY_R_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* DIS Experimental V-DIS PDUs
*/
DIS_ParserNode DIS_PARSER_APPLICATION_CONTROL_PDU[] =
{
{ DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
{ DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "Time Interval",0,0,0,0 },
{ DIS_FIELDTYPE_CONTROL_ID, "Control ID",0,0,0,0 },
{ DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 },
{ DIS_FIELDTYPE_APPLICATION_TYPE, "Originating App Type",0,0,0,0 },
{ DIS_FIELDTYPE_APPLICATION_TYPE, "Receiving App Type",0,0,0,0 },
{ DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "Number of Parts",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "Current Part",0,0,0,0 },
{ DIS_FIELDTYPE_UINT16, "Number of Variable Records",0,0,0,&numVariable },
{ DIS_FIELDTYPE_VARIABLE_RECORDS, "Record",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* Persistent Object (PO) Family PDU parsers
*/
DIS_ParserNode DIS_PARSER_SIMULATOR_PRESENT_PO_PDU[] =
{
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Simulator",0,0,0,0 },
{ DIS_FIELDTYPE_UINT16, "Simulator Type",0,0,0,0 },
{ DIS_FIELDTYPE_UINT32, "Database Sequence Number",0,0,0,0 },
{ DIS_FIELDTYPE_UINT32, "Simulator Load",0,0,0,0 },
{ DIS_FIELDTYPE_FLOAT32, "Simulation Load",0,0,0,0 },
{ DIS_FIELDTYPE_UINT32, "Time",0,0,0,0 },
{ DIS_FIELDTYPE_UINT32, "Packets Sent",0,0,0,0 },
{ DIS_FIELDTYPE_UINT16, "Unit Database Version",0,0,0,0 },
{ DIS_FIELDTYPE_UINT16, "Relative Battle Scheme",0,0,0,0 },
{ DIS_FIELDTYPE_FIXED_LEN_STR, "Terrain Name",32,0,0,0 },
{ DIS_FIELDTYPE_UINT16, "Terrain Version",0,0,0,0 },
{ DIS_FIELDTYPE_FIXED_LEN_STR, "Host Name",32,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_DESCRIBE_OBJECT_PO_PDU[] =
{
{ DIS_FIELDTYPE_UINT32, "Database Sequence Number",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "Object ID",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Owner",0,0,0,0 },
{ DIS_FIELDTYPE_UINT16, "Sequence Number",0,0,0,0 },
{ DIS_FIELDTYPE_PERSISTENT_OBJECT_CLASS, "Object Class",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "Missing From World State",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_OBJECTS_PRESENT_PO_PDU[] =
{
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Owner",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "Object Count",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_OBJECT_REQUEST_PO_PDU[] =
{
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Requesting Simulator",0,0,0,0 },
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Object Owner",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "Object Count",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_DELETE_OBJECTS_PO_PDU[] =
{
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Requesting Simulator",0,0,0,0 },
{ DIS_FIELDTYPE_UINT8, "Object Count",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_SET_WORLD_STATE_PO_PDU[] =
{
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Requesting Simulator",0,0,0,0 },
{ DIS_FIELDTYPE_FLOAT32, "Clock Rate",0,0,0,0 },
{ DIS_FIELDTYPE_UINT32, "Seconds Since 1970",0,0,0,0 },
{ DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
DIS_ParserNode DIS_PARSER_NOMINATION_PO_PDU[] =
{
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Nominated Simulator",0,0,0,0 },
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Nominating Simulator",0,0,0,0 },
{ DIS_FIELDTYPE_SIMULATION_ADDRESS, "Missing Simulator",0,0,0,0 },
{ DIS_FIELDTYPE_END, NULL,0,0,0,0 }
};
/* Initialize the parsers for each PDU type and the standard DIS header.
*/
void initializeParsers(void)
{
gint *ett[DIS_PDU_MAX_VARIABLE_PARAMETERS+DIS_PDU_MAX_VARIABLE_RECORDS+2];
int i, ett_index;
initializeParser(DIS_FIELDS_PDU_HEADER);
/* DIS Entity Information / Interaction PDUs */
initializeParser(DIS_PARSER_ENTITY_STATE_PDU);
/* DIS Distributed Emission Regeneration PDUs */
initializeParser(DIS_PARSER_ELECTROMAGNETIC_EMISSION_PDU);
initializeParser(DIS_PARSER_UNDERWATER_ACOUSTIC_PDU);
/* DIS Radio Communications protocol (RCP) family PDUs */
initializeParser(DIS_PARSER_TRANSMITTER_PDU);
initializeParser(DIS_PARSER_SIGNAL_PDU);
/* DIS Warfare PDUs */
initializeParser(DIS_PARSER_FIRE_PDU);
initializeParser(DIS_PARSER_DETONATION_PDU);
/* DIS Simulation Management PDUs */
initializeParser(DIS_PARSER_START_RESUME_PDU);
initializeParser(DIS_PARSER_STOP_FREEZE_PDU);
initializeParser(DIS_PARSER_ACKNOWLEDGE_PDU);
initializeParser(DIS_PARSER_ACTION_REQUEST_PDU);
initializeParser(DIS_PARSER_ACTION_RESPONSE_PDU);
initializeParser(DIS_PARSER_DATA_PDU);
initializeParser(DIS_PARSER_DATA_QUERY_PDU);
initializeParser(DIS_PARSER_COMMENT_PDU);
initializeParser(DIS_PARSER_SIMAN_ENTITY_PDU);
/* DIS Simulation Management with Reliability PDUs */
initializeParser(DIS_PARSER_START_RESUME_R_PDU);
initializeParser(DIS_PARSER_STOP_FREEZE_R_PDU);
initializeParser(DIS_PARSER_ACTION_REQUEST_R_PDU);
initializeParser(DIS_PARSER_DATA_R_PDU);
initializeParser(DIS_PARSER_DATA_QUERY_R_PDU);
initializeParser(DIS_PARSER_SIMAN_ENTITY_R_PDU);
/* DIS Experimental V-DIS PDUs */
initializeParser(DIS_PARSER_APPLICATION_CONTROL_PDU);
/* Initialize the Persistent Object PDUs */
initializeParser(DIS_FIELDS_PERSISTENT_OBJECT_HEADER);
initializeParser(DIS_PARSER_DESCRIBE_OBJECT_PO_PDU);
initializeParser(DIS_PARSER_SIMULATOR_PRESENT_PO_PDU);
initializeParser(DIS_PARSER_OBJECTS_PRESENT_PO_PDU);
initializeParser(DIS_PARSER_OBJECT_REQUEST_PO_PDU);
initializeParser(DIS_PARSER_DELETE_OBJECTS_PO_PDU);
initializeParser(DIS_PARSER_SET_WORLD_STATE_PO_PDU);
initializeParser(DIS_PARSER_NOMINATION_PO_PDU);
/* Initialize the ett array */
ett_index = 0;
for (i=0; i<DIS_PDU_MAX_VARIABLE_PARAMETERS; i++, ett_index++)
{
ettVariableParameters[i] = -1;
ett[ett_index] = &ettVariableParameters[i];
}
for (i=0; i<DIS_PDU_MAX_VARIABLE_RECORDS; i++, ett_index++)
{
ettVariableRecords[i] = -1;
ett[ett_index] = &ettVariableRecords[i];
}
ett[ett_index++] = &ettFixedData;
ett[ett_index++] = &ettVariableData;
proto_register_subtree_array(ett, array_length(ett));
}
/* Create a specific subtree for a PDU or a composite PDU field.
*/
DIS_ParserNode *createSubtree(DIS_ParserNode parserNodes[], gint *ettVar)
{
guint fieldIndex = 0;
guint fieldCount;
gint *ett[1];
DIS_ParserNode *newSubtree;
while (parserNodes[fieldIndex].fieldType != DIS_FIELDTYPE_END)
{
++fieldIndex;
}
fieldCount = fieldIndex + 1;
newSubtree = (DIS_ParserNode*)g_malloc(sizeof(DIS_ParserNode) * fieldCount);
memcpy(newSubtree, parserNodes, sizeof(DIS_ParserNode) * fieldCount);
initializeParser(newSubtree);
*ettVar = -1;
ett[0] = ettVar;
proto_register_subtree_array(ett, array_length(ett));
return newSubtree;
}
/* Initialize an array of parser nodes.
*/
void initializeParser(DIS_ParserNode parserNodes[])
{
guint parserIndex = 0;
/* Create the parser subtrees for each of the composite field types.
*/
while (parserNodes[parserIndex].fieldType != DIS_FIELDTYPE_END)
{
switch (parserNodes[parserIndex].fieldType)
{
/* Bit fields */
case DIS_FIELDTYPE_APPEARANCE:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_NONE,
&parserNodes[parserIndex].ettVar);
break;
/* Composite types */
case DIS_FIELDTYPE_MOD_PARAMS_CCTT_SINCGARS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_MOD_PARAMS_JTIDS_MIDS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_BURST_DESCRIPTOR:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_BURST_DESCRIPTOR,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_CLOCK_TIME:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_CLOCK_TIME,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_ENTITY_ID:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_ENTITY_ID,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_ENTITY_TYPE:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_ENTITY_TYPE,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_RADIO_ENTITY_TYPE:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_RADIO_ENTITY_TYPE,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_EVENT_ID:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_EVENT_ID,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_ORIENTATION:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_ORIENTATION,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_SIMULATION_ADDRESS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_SIMULATION_ADDRESS,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_LINEAR_VELOCITY:
case DIS_FIELDTYPE_LOCATION_ENTITY:
case DIS_FIELDTYPE_REL_ANTENNA_LOCATON:
case DIS_FIELDTYPE_VECTOR_32:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VECTOR_FLOAT_32,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_LOCATION_WORLD:
case DIS_FIELDTYPE_ANTENNA_LOCATION:
case DIS_FIELDTYPE_VECTOR_64:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VECTOR_FLOAT_64,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_MODULATION_TYPE:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_MODULATION_TYPE,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_EMITTER_SYSTEM:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_EMITTER_SYSTEM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_FUNDAMENTAL_PARAMETER_DATA:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_FUNDAMENTAL_PARAMETER_DATA,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_TRACK_JAM:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_TRACK_JAM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_SHAFTS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VR_UA_SHAFT,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_APA:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VR_APA,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_UA_EMITTER_SYSTEMS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VR_UA_EMITTER_SYSTEM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_UA_EMITTER_SYSTEM:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_UA_EMITTER_SYSTEM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_UA_BEAMS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VR_UA_BEAM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_UA_BEAM_FUNDAMENTAL_PARAMETER_DATA:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_UA_BEAM_FUNDAMENTAL_PARAMETER_DATA,
&parserNodes[parserIndex].ettVar);
break;
/* Array records */
case DIS_FIELDTYPE_FIXED_DATUMS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_FIXED_DATUM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_VARIABLE_DATUMS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VARIABLE_DATUM,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_FIXED_DATUM_IDS:
case DIS_FIELDTYPE_VARIABLE_DATUM_IDS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_DATUM_IDS,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_VARIABLE_PARAMETERS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VP_TYPE,
&parserNodes[parserIndex].ettVar);
break;
case DIS_FIELDTYPE_VARIABLE_RECORDS:
parserNodes[parserIndex].children = createSubtree(
DIS_FIELDS_VR_TYPE,
&parserNodes[parserIndex].ettVar);
break;
default:
break;
}
++parserIndex;
}
}
/* Parse packet data based on a specified array of DIS_ParserNodes.
*/
gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[])
{
guint fieldIndex = 0;
guint fieldRepeatLen = 0;
guint64 uintVal = 0;
proto_item *pi = NULL;
proto_tree *sub_tree = NULL;
tvbuff_t *newtvb = NULL;
gint length = 0;
guint16 spread_spectrum = 0;
/* Get the length while ensuring there's at least one byte for us to
* decode (if not, throw an exception so as to prevent very long loops).
*/
length = tvb_ensure_length_remaining(tvb, offset+1);
while ((parserNodes[fieldIndex].fieldType != DIS_FIELDTYPE_END)
&& (length > 0 ) )
{
proto_item *newField = 0;
fieldRepeatLen = (guint) ((parserNodes[fieldIndex].fieldRepeatLen > 1) ?
parserNodes[fieldIndex].fieldRepeatLen : 1);
switch(parserNodes[fieldIndex].fieldType)
{
/* basic numeric types */
case DIS_FIELDTYPE_INT8:
offset = parseField_Int(tvb, tree, offset,
parserNodes[fieldIndex], 1);
break;
case DIS_FIELDTYPE_INT16:
offset = parseField_Int(tvb, tree, offset,
parserNodes[fieldIndex], 2);
break;
case DIS_FIELDTYPE_INT32:
offset = parseField_Int(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_INT64:
offset = parseField_Int(tvb, tree, offset,
parserNodes[fieldIndex], 8);
break;
case DIS_FIELDTYPE_UINT8:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 1);
break;
case DIS_FIELDTYPE_UINT16:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 2);
break;
case DIS_FIELDTYPE_UINT32:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_UINT64:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 8);
break;
case DIS_FIELDTYPE_FLOAT32:
offset = parseField_Float(tvb, tree, offset,
parserNodes[fieldIndex]);
break;
case DIS_FIELDTYPE_FLOAT64:
offset = parseField_Double(tvb, tree, offset,
parserNodes[fieldIndex]);
break;
case DIS_FIELDTYPE_EXERCISE_ID:
proto_tree_add_item(tree, hf_dis_exercise_id, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_NUM_ARTICULATION_PARAMS:
uintVal = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_dis_num_art_params, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
break;
case DIS_FIELDTYPE_PDU_LENGTH:
proto_tree_add_item(tree, hf_dis_pdu_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_SITE:
proto_tree_add_item(tree, hf_dis_entity_id_site, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_APPLICATION:
proto_tree_add_item(tree, hf_dis_entity_id_application, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_ENTITY:
proto_tree_add_item(tree, hf_dis_entity_id_entity, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_RADIO_ID:
uintVal = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_dis_radio_id, tvb, offset, 2, ENC_BIG_ENDIAN);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 2;
break;
case DIS_FIELDTYPE_ENCODING_SCHEME:
uintVal = tvb_get_ntohs(tvb, offset);
pi = proto_tree_add_item(tree, hf_dis_ens, tvb, offset, 2, ENC_BIG_ENDIAN);
sub_tree = proto_item_add_subtree(pi, ett_dis_ens);
proto_tree_add_item(sub_tree, hf_dis_ens_class, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(sub_tree, hf_dis_ens_type, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_item_set_end(pi, tvb, offset);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 2;
break;
case DIS_FIELDTYPE_TDL_TYPE:
proto_tree_add_item(tree, hf_dis_tdl_type, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_SAMPLE_RATE:
proto_tree_add_item(tree, hf_dis_sample_rate, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
break;
case DIS_FIELDTYPE_DATA_LENGTH:
proto_tree_add_item(tree, hf_dis_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_NUMBER_OF_SAMPLES:
uintVal = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_dis_num_of_samples, tvb, offset, 2, ENC_BIG_ENDIAN);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 2;
break;
case DIS_FIELDTYPE_RADIO_DATA:
newtvb = tvb_new_subset_remaining(tvb, offset);
proto_tree_add_item(tree, hf_dis_signal_data, newtvb, 0, -1, ENC_NA );
/* ****ck******* need to look for padding bytes */
break;
case DIS_FIELDTYPE_RADIO_CATEGORY:
proto_tree_add_item(tree, hf_dis_radio_category, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_NOMENCLATURE_VERSION:
proto_tree_add_item(tree, hf_dis_nomenclature_version, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_NOMENCLATURE:
proto_tree_add_item(tree, hf_dis_nomenclature, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_RADIO_TRANSMIT_STATE:
uintVal = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_dis_radio_transmit_state, tvb, offset, 1, ENC_BIG_ENDIAN);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 1;
break;
case DIS_FIELDTYPE_RADIO_INPUT_SOURCE:
proto_tree_add_item(tree, hf_dis_radio_input_source, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_ANTENNA_PATTERN_TYPE:
uintVal = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_dis_antenna_pattern_type, tvb, offset, 2, ENC_BIG_ENDIAN);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 2;
break;
case DIS_FIELDTYPE_ANTENNA_PATTERN_LENGTH:
proto_tree_add_item(tree, hf_dis_antenna_pattern_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_TRANSMIT_FREQUENCY:
proto_tree_add_item(tree, hf_dis_transmit_frequency, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
break;
case DIS_FIELDTYPE_SPREAD_SPECTRUM:
spread_spectrum = tvb_get_ntohs(tvb, offset);
proto_tree_add_boolean(tree, hf_dis_spread_spectrum_usage, tvb, offset, 2, spread_spectrum);
proto_tree_add_boolean(tree, hf_dis_frequency_hopping, tvb, offset, 2, spread_spectrum);
proto_tree_add_boolean(tree, hf_dis_pseudo_noise_modulation, tvb, offset, 2, spread_spectrum);
proto_tree_add_boolean(tree, hf_dis_time_hopping, tvb, offset, 2, spread_spectrum);
offset += 2;
break;
case DIS_FIELDTYPE_MODULATION_MAJOR:
uintVal = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_dis_modulation_major, tvb, offset, 2, ENC_BIG_ENDIAN);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 2;
break;
case DIS_FIELDTYPE_MODULATION_SYSTEM:
uintVal = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_dis_modulation_system, tvb, offset, 2, ENC_BIG_ENDIAN);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 2;
break;
case DIS_FIELDTYPE_CRYPTO_SYSTEM:
proto_tree_add_item(tree, hf_dis_crypto_system, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_CRYPTO_KEY_ID:
pi = proto_tree_add_item(tree, hf_dis_crypto_key, tvb, offset, 2, ENC_BIG_ENDIAN);
sub_tree = proto_item_add_subtree(pi, ett_dis_crypto_key);
proto_tree_add_item(sub_tree, hf_dis_encryption_mode, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(sub_tree, hf_dis_key_identifier, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_item_set_end(pi, tvb, offset);
offset += 2;
break;
case DIS_FIELDTYPE_MODULATION_PARAMETER_LENGTH:
uintVal = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_dis_modulation_parameter_length, tvb, offset, 1, ENC_BIG_ENDIAN);
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
offset += 1;
break;
case DIS_FIELDTYPE_FH_NETWORK_ID:
proto_tree_add_item(tree, hf_dis_mod_param_fh_net_id, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_FH_SET_ID:
proto_tree_add_item(tree, hf_dis_mod_param_fh_set_id, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_LO_SET_ID:
proto_tree_add_item(tree, hf_dis_mod_param_fh_lo_set_id, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_FH_MSG_START:
proto_tree_add_item(tree, hf_dis_mod_param_fh_msg_start, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_RESERVED:
proto_tree_add_item(tree, hf_dis_mod_param_fh_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_FH_SYNC_TIME_OFFSET:
proto_tree_add_item(tree, hf_dis_mod_param_fh_sync_time_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
break;
case DIS_FIELDTYPE_FH_SECURITY_KEY:
proto_tree_add_item(tree, hf_dis_mod_param_fh_security_key, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case DIS_FIELDTYPE_FH_CLEAR_CHANNEL:
proto_tree_add_item(tree, hf_dis_mod_param_fh_clear_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_TS_ALLOCATION_MODE:
proto_tree_add_item(tree, hf_dis_mod_param_ts_allocation_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_TRANSMITTER_PRIMARY_MODE:
proto_tree_add_item(tree, hf_dis_mod_param_transmitter_prim_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_TRANSMITTER_SECONDARY_MODE:
proto_tree_add_item(tree, hf_dis_mod_param_transmitter_second_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_JTIDS_SYNC_STATE:
proto_tree_add_item(tree, hf_dis_mod_param_sync_state, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case DIS_FIELDTYPE_NETWORK_SYNC_ID:
proto_tree_add_item(tree, hf_dis_mod_param_network_sync_id, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
break;
case DIS_FIELDTYPE_MODULATION_PARAMETERS:
/* need to check to see if mod parms length > 0 */
/* could get here when there are antenna pattern parameter but no mod params */
if (modulationParamLength > 0 ) { /* we do have a mod param */
if (systemModulation == DIS_SYSTEM_MOD_CCTT_SINCGARS)
{
pi = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
sub_tree = proto_item_add_subtree(pi, parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS);
proto_item_set_end(pi, tvb, offset);
break;
}
else if (systemModulation == DIS_SYSTEM_MOD_JTIDS_MIDS) {
pi = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
sub_tree = proto_item_add_subtree(pi, parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS);
proto_item_set_end(pi, tvb, offset);
break;
}
else { /* just dump what is available */
newtvb = tvb_new_subset(tvb, offset,modulationParamLength, modulationParamLength);
proto_tree_add_item(tree, hf_dis_mod_param_dump, newtvb, 0, -1, ENC_NA );
offset += modulationParamLength;
break;
}
} /* else, leave offset alone, and then check antenna pattern param field */
break;
case DIS_FIELDTYPE_ANTENNA_PATTERN_PARAMETERS:
/* just dump the bytes for now. Need to do finish */
newtvb = tvb_new_subset_remaining(tvb, offset);
proto_tree_add_item(tree, hf_dis_antenna_pattern_parameter_dump, newtvb, 0, -1, ENC_NA );
break;
/* padding */
case DIS_FIELDTYPE_PAD8:
offset = parseField_Pad(tvb, tree, offset,
parserNodes[fieldIndex], 1 * fieldRepeatLen);
break;
case DIS_FIELDTYPE_PAD16:
offset = parseField_Pad(tvb, tree, offset,
parserNodes[fieldIndex], 2 * fieldRepeatLen);
break;
case DIS_FIELDTYPE_PAD24:
offset = parseField_Pad(tvb, tree, offset,
parserNodes[fieldIndex], 3 * fieldRepeatLen);
break;
case DIS_FIELDTYPE_PAD32:
offset = parseField_Pad(tvb, tree, offset,
parserNodes[fieldIndex], 4 * fieldRepeatLen);
break;
/* enumerations (1-byte) */
case DIS_FIELDTYPE_APPLICATION_GENERAL_STATUS:
case DIS_FIELDTYPE_CATEGORY:
case DIS_FIELDTYPE_CONTROL_ID:
case DIS_FIELDTYPE_DETONATION_RESULT:
case DIS_FIELDTYPE_DOMAIN:
case DIS_FIELDTYPE_ENTITY_KIND:
case DIS_FIELDTYPE_FROZEN_BEHAVIOR:
case DIS_FIELDTYPE_PARAMETER_TYPE_DESIGNATOR:
case DIS_FIELDTYPE_PDU_TYPE:
case DIS_FIELDTYPE_PROTOCOL_FAMILY:
case DIS_FIELDTYPE_PROTOCOL_VERSION:
case DIS_FIELDTYPE_REASON:
case DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE:
case DIS_FIELDTYPE_PERSISTENT_OBJECT_CLASS:
case DIS_FIELDTYPE_PERSISTENT_OBJECT_TYPE:
case DIS_FIELDTYPE_EMISSION_FUNCTION:
case DIS_FIELDTYPE_BEAM_FUNCTION:
offset = parseField_Enum(tvb, tree, offset,
parserNodes[fieldIndex], 1);
break;
/* enumerations (2-bytes) */
case DIS_FIELDTYPE_ACKNOWLEDGE_FLAG:
case DIS_FIELDTYPE_APPLICATION_STATUS_TYPE:
case DIS_FIELDTYPE_APPLICATION_TYPE:
case DIS_FIELDTYPE_RESPONSE_FLAG:
case DIS_FIELDTYPE_MODULATION_DETAIL:
case DIS_FIELDTYPE_EMITTER_NAME:
offset = parseField_Enum(tvb, tree, offset,
parserNodes[fieldIndex], 2);
break;
/* enumerations (4-bytes) */
case DIS_FIELDTYPE_ACTION_ID:
case DIS_FIELDTYPE_REQUEST_STATUS:
offset = parseField_Enum(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
/* other atomic types */
case DIS_FIELDTYPE_APPEARANCE:
{
proto_item *newSubtree;
newField = proto_tree_add_text(tree, tvb, offset, 4, "%s",
parserNodes[fieldIndex].fieldLabel);
newSubtree = proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseField_Bitmask(tvb, newSubtree, offset,
parserNodes[fieldIndex], 4);
}
break;
case DIS_FIELDTYPE_ARTIC_PARAM_TYPE:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_CAPABILITIES:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_COUNTRY:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 2);
break;
case DIS_FIELDTYPE_DATUM_ID:
case DIS_FIELDTYPE_DATUM_LENGTH:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_DEAD_RECKONING_PARAMS:
/* This is really a struct... needs a field parser.
* For now, just skip the 12 bytes.
*/
offset = parseField_Bytes(tvb, tree, offset,
parserNodes[fieldIndex], 40);
break;
case DIS_FIELDTYPE_ENTITY_MARKING:
/* This is really a struct... needs a field parser.
* For now, just skip the 12 bytes.
*/
offset = parseField_Bytes(tvb, tree, offset,
parserNodes[fieldIndex], 12);
break;
case DIS_FIELDTYPE_EXTRA:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 1);
break;
case DIS_FIELDTYPE_FIXED_DATUM_VALUE:
offset = parseField_Bytes(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_FIXED_LEN_STR:
offset = parseField_Bytes(tvb, tree, offset,
parserNodes[fieldIndex],
parserNodes[fieldIndex].fieldRepeatLen);
break;
case DIS_FIELDTYPE_FORCE_ID:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 1);
break;
case DIS_FIELDTYPE_FUSE:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 2);
break;
case DIS_FIELDTYPE_NUM_FIXED_DATA:
case DIS_FIELDTYPE_NUM_VARIABLE_DATA:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_REQUEST_ID:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_SPECIFIC:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 1);
break;
case DIS_FIELDTYPE_SUBCATEGORY:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 1);
break;
case DIS_FIELDTYPE_TIME_INTERVAL:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 4);
break;
case DIS_FIELDTYPE_TIMESTAMP:
offset = parseField_Timestamp(tvb, tree, offset,
parserNodes[fieldIndex]);
break;
case DIS_FIELDTYPE_WARHEAD:
offset = parseField_UInt(tvb, tree, offset,
parserNodes[fieldIndex], 2);
break;
/* composite types */
case DIS_FIELDTYPE_BURST_DESCRIPTOR:
case DIS_FIELDTYPE_CLOCK_TIME:
case DIS_FIELDTYPE_ENTITY_ID:
case DIS_FIELDTYPE_ENTITY_TYPE:
case DIS_FIELDTYPE_RADIO_ENTITY_TYPE:
case DIS_FIELDTYPE_ANTENNA_LOCATION:
case DIS_FIELDTYPE_REL_ANTENNA_LOCATON:
case DIS_FIELDTYPE_EVENT_ID:
case DIS_FIELDTYPE_LINEAR_VELOCITY:
case DIS_FIELDTYPE_LOCATION_ENTITY:
case DIS_FIELDTYPE_LOCATION_WORLD:
case DIS_FIELDTYPE_ORIENTATION:
case DIS_FIELDTYPE_SIMULATION_ADDRESS:
case DIS_FIELDTYPE_VECTOR_32:
case DIS_FIELDTYPE_VECTOR_64:
case DIS_FIELDTYPE_MODULATION_TYPE:
case DIS_FIELDTYPE_EMITTER_SYSTEM:
case DIS_FIELDTYPE_FUNDAMENTAL_PARAMETER_DATA:
case DIS_FIELDTYPE_UA_EMITTER_SYSTEM:
case DIS_FIELDTYPE_UA_BEAM_FUNDAMENTAL_PARAMETER_DATA:
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree = proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
break;
case DIS_FIELDTYPE_VARIABLE_DATUM_VALUE:
{
guint lengthInBytes;
lengthInBytes = variableDatumLength / 8;
if (variableDatumLength % 8 > 0)
{
lengthInBytes += (8 - (variableDatumLength % 8));
}
offset = parseField_Bytes(tvb, tree, offset,
parserNodes[fieldIndex], lengthInBytes);
}
break;
/* arrays */
case DIS_FIELDTYPE_FIXED_DATUMS:
{
guint i;
if (numFixed > INT32_MAX)
{
numFixed = INT32_MAX;
}
for (i = 0; i < numFixed; ++i)
{
proto_item *newSubtree;
/* is remaining length large enough for another fixed datum (ID & value) */
/* XXX is this really necessary? */
tvb_ensure_length_remaining(tvb, offset+8);
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
newSubtree = proto_item_add_subtree(newField, ettFixedData);
offset = parseFields (tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_FIXED_DATUM_IDS:
if (numFixed > 0)
{
guint i;
proto_item *newSubtree;
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
newSubtree = proto_item_add_subtree(newField, ettFixedData);
if (numFixed > INT32_MAX)
{
numFixed = INT32_MAX;
}
for (i = 0; i < numFixed; ++i)
{
/* is remaining length large enough for another fixed datum ID (32 bit int) */
/* XXX is this really necessary? */
tvb_ensure_length_remaining(tvb, offset+4);
offset = parseFields (tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
break;
case DIS_FIELDTYPE_VARIABLE_DATUMS:
{
guint i;
if (numVariable > INT32_MAX)
{
numVariable = INT32_MAX;
}
for (i = 0; i < numVariable; ++i)
{
proto_item *newSubtree;
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
newSubtree = proto_item_add_subtree
(newField, ettVariableData);
offset = parseFields
(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_VARIABLE_DATUM_IDS:
if (numVariable > 0)
{
guint i;
proto_item *newSubtree;
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
newSubtree = proto_item_add_subtree(newField, ettVariableData);
if (numVariable > INT32_MAX)
{
numVariable = INT32_MAX;
}
for (i = 0; i < numVariable; ++i)
{
offset = parseFields
(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
break;
case DIS_FIELDTYPE_VARIABLE_PARAMETERS:
{
guint i;
if (numVariable > DIS_PDU_MAX_VARIABLE_PARAMETERS)
{
numVariable = DIS_PDU_MAX_VARIABLE_PARAMETERS;
}
for (i = 0; i < numVariable; ++i)
{
proto_item *newSubtree;
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
newSubtree = proto_item_add_subtree(newField,
ettVariableParameters[i]);
offset = parseFields
(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
offset = parseField_VariableParameter
(tvb, newSubtree, offset);
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_VARIABLE_RECORDS:
{
guint i;
if (numVariable > DIS_PDU_MAX_VARIABLE_RECORDS)
{
numVariable = DIS_PDU_MAX_VARIABLE_RECORDS;
}
for (i = 0; i < numVariable; ++i)
{
proto_item *newSubtree;
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
newSubtree = proto_item_add_subtree(newField,
ettVariableRecords[i]);
offset = parseFields
(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
offset = parseField_VariableRecord
(tvb, newSubtree, offset);
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM:
{
guint i;
for (i = 0; i < numBeams; ++i)
{
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree =
proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_TRACK_JAM:
{
guint i;
for (i = 0; i < numTrackJamTargets; ++i)
{
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree =
proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_NUM_ELECTROMAGNETIC_EMISSION_SYSTEMS:
uintVal = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_dis_num_electromagnetic_emission_systems, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
break;
case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM:
{
guint i;
if (numVariable > DIS_PDU_MAX_ELECTROMAGNETIC_EMISSION_SYSTEMS)
{
numVariable = DIS_PDU_MAX_ELECTROMAGNETIC_EMISSION_SYSTEMS;
}
for (i = 0; i < numVariable; ++i)
{
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
parserNodes[fieldIndex].fieldLabel);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree =
proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_NUM_OF_SHAFTS:
{
uintVal = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_dis_num_shafts, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
}
break;
case DIS_FIELDTYPE_SHAFTS:
{
guint i;
if (numShafts > DIS_PDU_MAX_SHAFTS)
{
numShafts = DIS_PDU_MAX_SHAFTS;
}
for (i = 0; i < numShafts; ++i)
{
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s [%d of %d]",
parserNodes[fieldIndex].fieldLabel, i+1, numShafts);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree =
proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_NUM_OF_APAS:
{
uintVal = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_dis_num_apas, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
}
break;
case DIS_FIELDTYPE_APA:
{
guint i;
if (numApas > DIS_PDU_MAX_APAS)
{
numApas = DIS_PDU_MAX_APAS;
}
for (i = 0; i < numApas; ++i)
{
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s [%d of %d]",
parserNodes[fieldIndex].fieldLabel, i+1, numApas);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree =
proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_NUM_OF_UA_EMITTER_SYSTEMS:
{
uintVal = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_dis_num_ua_emitter_systems, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
*(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
}
break;
case DIS_FIELDTYPE_NUM_OF_UA_EMITTER_SYSTEM_BEAMS:
{
uintVal = tvb_get_guint8(tvb, offset);
offset = parseField_UInt(tvb, tree, offset, parserNodes[fieldIndex], 1);
numUABeams += (guint32)uintVal;
}
break;
case DIS_FIELDTYPE_UA_EMITTER_SYSTEMS:
{
guint i;
if (numUAEmitter > DIS_PDU_MAX_UA_EMITTER_SYSTEMS)
{
numUAEmitter = DIS_PDU_MAX_UA_EMITTER_SYSTEMS;
}
for (i = 0; i < numUAEmitter; ++i)
{
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s [%d of %d]",
parserNodes[fieldIndex].fieldLabel, i+1, numUAEmitter);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree =
proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
}
break;
case DIS_FIELDTYPE_UA_BEAMS:
{
guint i;
if (numUABeams > DIS_PDU_MAX_UA_BEAMS)
{
numUABeams = DIS_PDU_MAX_UA_BEAMS;
}
for (i = 0; i < numUABeams; ++i)
{
newField = proto_tree_add_text(tree, tvb, offset, -1, "%s [%d of %d]",
parserNodes[fieldIndex].fieldLabel, i+1, numUABeams);
if (parserNodes[fieldIndex].children != 0)
{
proto_item *newSubtree =
proto_item_add_subtree(newField,
parserNodes[fieldIndex].ettVar);
offset = parseFields(tvb, newSubtree, offset,
parserNodes[fieldIndex].children);
}
proto_item_set_end(newField, tvb, offset);
}
numUABeams = 0; /* reset beam count for this pdu */
}
break;
default:
break;
}
++fieldIndex;
length = tvb_length_remaining(tvb, offset);
}
return offset;
}