The lgrModSqlExporter dynamic library creates a replacement for the lgrSqlExporter (found in lgrConfigDIS.xml).
//! For DIS, this replacement adds an encoder for the Data PDU. It specifically collects only the datum containing VR-Forces control messages. There is more general code available to capture other datum; however, the interpretation of the datum values must be added.
The shared library is also built for the HLA protocols, but it does not add anything as the HLA encoder uses the omtReader to automatically encode the data.
#if DtDIS
#include <vl/dataPdu.h>
namespace MAKLogger
{
DtLgrDataPduEncoder::DtLgrDataPduEncoder()
: myTableName("DataPdu")
, mySenderIdColumn(0)
, myReceiverIdColumn(0)
, myNumberOfFixedDatumColumn(0)
, myNumberOfVariableDatumColumn(0)
, myFixedDatumParameterName("DataPdu_FixedDatums")
, myFixedDatumParameterTableIndex(0)
, myVariableDatumParameterName("DataPdu_VariableDatums")
, myVariableDatumParameterTableIndex(0)
, myFixedDatumIdColumn(0)
, myFixedDatumValueColumn(0)
, myVariableDatumIdColumn(0)
, myVariableDatumValueColumn(0)
{
mySenderIdColumn->setNullAllow(false);
myReceiverIdColumn->setNullAllow(false);
myNumberOfFixedDatumColumn->setNullAllow(false);
myNumberOfVariableDatumColumn->setNullAllow(false);
myFixedDatumIdColumn->setNullAllow(false);
myFixedDatumValueColumn->setNullAllow(false);
myVariableDatumIdColumn->setNullAllow(false);
myVariableDatumValueColumn->setNullAllow(false);
}
DtLgrDataPduEncoder::~DtLgrDataPduEncoder()
{
delete mySenderIdColumn;
delete myReceiverIdColumn;
delete myNumberOfFixedDatumColumn;
delete myNumberOfVariableDatumColumn;
delete myFixedDatumIdColumn;
delete myFixedDatumValueColumn;
delete myVariableDatumIdColumn;
delete myVariableDatumValueColumn;
}
DtPduKind DtLgrDataPduEncoder::pduKind()
{
return DtDataPduKind;
}
const DtString& DtLgrDataPduEncoder::pduName()
const
{
return myTableName;
}
std::vector<DtDatabaseTableSP> DtLgrDataPduEncoder::getTableDefinitions() const
{
std::vector<DtDatabaseTableSP> tables = DtLgrPduDatabaseEncoder::getTableDefinitions();
primary->addColumn(*mySenderIdColumn);
primary->addColumn(*myReceiverIdColumn);
primary->addColumn(*myNumberOfFixedDatumColumn);
primary->addColumn(*myNumberOfVariableDatumColumn);
secondary->
addColumn(*myFixedDatumValueColumn);
myFixedDatumParameterTableIndex = tables.size();
tertiary->
addColumn(*myVariableDatumIdColumn);
tertiary->
addColumn(*myVariableDatumValueColumn);
myVariableDatumParameterTableIndex = tables.size();
return tables;
}
#define DtControlMessage 260020
enum controlMessage
{
DtUnknownControlType = 0,
DtPauseControlType = 1,
DtRunControlType = 2,
DtRunDurationControlType = 3,
DtRunCompleteControlType = 4,
DtRewindControlType = 5,
DtStepControlType = 6
};
struct DtNetIfControl
{
DtNetFloat64 myTime;
DtNetU16 myControlType;
DtNetU32 myPadding1;
DtNetU16 myPadding2;
};
void getControlType(
const char* data,
DtString& datumValue)
{
if (!data)
return;
DtNetIfControl* controlData = (DtNetIfControl*)data;
switch ((DtU16)controlData->myControlType)
{
case DtPauseControlType:
{
datumValue = "Pause";
break;
}
case DtRunControlType:
{
datumValue = "Run";
break;
}
case DtRunDurationControlType:
{
datumValue = "RunDuration";
break;
}
case DtRunCompleteControlType:
{
datumValue = "RunComplete";
break;
}
case DtRewindControlType:
{
datumValue = "Rewind";
break;
}
case DtStepControlType:
{
datumValue = "Step";
break;
}
case DtUnknownControlType:
default:
{
datumValue = "UnknownControl";
break;
}
}
}
void DtLgrDataPduEncoder::encodePdu(
const DtPdu& pdu,std::vector<DtDatabaseTableSP>& tables )
const
{
const DtDataPdu& dataPdu = static_cast<const DtDataPdu&>(pdu);
#if 1
int recordCount = dataPdu.numVarFields();
unsigned long datumId = 0;
for( int recordIndex = 1; datumId != DtControlMessage && recordIndex <= recordCount; ++recordIndex)
{
datumId = dataPdu.varDatumId(recordIndex);
if (datumId == DtControlMessage)
{
getControlType(dataPdu.datumValByteArray(DtVar, recordIndex), controlType);
}
}
if (datumId == DtControlMessage)
{
primary->getColumn(mySenderIdColumn->columnName())->setValue(dataPdu.senderId().string());
primary->getColumn(myReceiverIdColumn->columnName())->setValue(dataPdu.receiverId().string());
primary->getColumn(myNumberOfFixedDatumColumn->columnName())->setValue(dataPdu.numFixedFields());
primary->getColumn(myNumberOfVariableDatumColumn->columnName())->setValue(dataPdu.numVarFields());
varTable->getColumn(myVariableDatumIdColumn->columnName())->addValue(DtControlMessage);
varTable->getColumn(myVariableDatumValueColumn->columnName())->addValue(controlType.c_str());
}
#else
primary->getColumn(mySenderIdColumn->columnName())->setValue(dataPdu.senderId().string());
primary->getColumn(myReceiverIdColumn->columnName())->setValue(dataPdu.receiverId().string());
primary->getColumn(myNumberOfFixedDatumColumn->columnName())->setValue(dataPdu.numFixedFields());
primary->getColumn(myNumberOfVariableDatumColumn->columnName())->setValue(dataPdu.numVarFields());
int recordCount = dataPdu.numFixedFields();
int recordIndex = 0;
for( ; recordIndex < recordCount; ++recordIndex)
{
int valueLength = dataPdu.datumSizeBytes(DtFixed, recordIndex);
bin2HexString(valueString, dataPdu.datumValByteArray(DtFixed, recordIndex), valueLength);
fixedTable->getColumn(myFixedDatumIdColumn->columnName())->addValue(dataPdu.fixedDatumId(recordIndex));
fixedTable->getColumn(myFixedDatumValueColumn->columnName())->addValue(valueString);
}
recordCount = dataPdu.numVarFields();
for( recordIndex = 0; recordIndex < recordCount; ++recordIndex)
{
int valueLength = dataPdu.datumSizeBytes(DtVar, recordIndex);
bin2HexString(valueString, dataPdu.datumValByteArray(DtVar, recordIndex), valueLength);
varTable->getColumn(myVariableDatumIdColumn->columnName())->addValue(dataPdu.varDatumId(recordIndex));
varTable->getColumn(myVariableDatumValueColumn->columnName())->addValue(valueString);
}
#endif
}
}
#endif