MAK Data Logger API Documentation for HLA
lgrModSqlExporter Example

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 because the HLA encoder uses the omtReader to automatically encode the data.


The Data PDU encoder:

/******************************************************************************
** Copyright (c) 1992-2014 VT MAK
** All rights reserved.
******************************************************************************/
#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 = new DtDatabaseColumn("SenderId",DtDatabaseColumn::Type_SqlVarString);
myReceiverIdColumn = new DtDatabaseColumn("ReceiverId",DtDatabaseColumn::Type_SqlVarString);
myNumberOfFixedDatumColumn = new DtDatabaseColumn("NumberOfFixedDatum",DtDatabaseColumn::Type_SqlUnsignedShort);
myNumberOfVariableDatumColumn = new DtDatabaseColumn("NumberOfVariableDatum",DtDatabaseColumn::Type_SqlUnsignedShort);
myFixedDatumIdColumn = new DtDatabaseColumn("FixedDatums_ID",DtDatabaseColumn::Type_SqlUnsignedLong);
myFixedDatumValueColumn = new DtDatabaseColumn("FixeDatums_Value",DtDatabaseColumn::Type_SqlVarString);
myVariableDatumIdColumn = new DtDatabaseColumn("VariableDatums_ID",DtDatabaseColumn::Type_SqlUnsignedLong);
myVariableDatumValueColumn = new DtDatabaseColumn("VariableDatums_Value",DtDatabaseColumn::Type_SqlVarString);
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();
DtDatabaseTableSP primary = tables.front();
primary->addColumn(*mySenderIdColumn);
primary->addColumn(*myReceiverIdColumn);
primary->addColumn(*myNumberOfFixedDatumColumn);
primary->addColumn(*myNumberOfVariableDatumColumn);
DtDatabaseTable* secondary = createSubTable(myFixedDatumParameterName);
secondary->addColumn(*myFixedDatumIdColumn);
secondary->addColumn(*myFixedDatumValueColumn);
myFixedDatumParameterTableIndex = tables.size();
tables.push_back(DtDatabaseTableSP(secondary));
DtDatabaseTable* tertiary = createSubTable(myVariableDatumParameterName);
tertiary->addColumn(*myVariableDatumIdColumn);
tertiary->addColumn(*myVariableDatumValueColumn);
myVariableDatumParameterTableIndex = tables.size();
tables.push_back(DtDatabaseTableSP(tertiary));
return tables;
}
// From vrfExtProtocol\msgTypes.h in makVrfVrlinkExtentions
#define DtControlMessage 260020
enum controlMessage
{
DtUnknownControlType = 0,
DtPauseControlType = 1,
DtRunControlType = 2,
DtRunDurationControlType = 3,
DtRunCompleteControlType = 4,
DtRewindControlType = 5,
DtStepControlType = 6
};
// From vrfMsgs\ifControl.h in VR-Forces
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);
DtDatabaseTableSP primary = tables.front();
DtDatabaseTableSP fixedTable = tables[myFixedDatumParameterTableIndex];
DtDatabaseTableSP varTable = tables[myVariableDatumParameterTableIndex];
int recordCount = dataPdu.numVarFields();
DtString controlType("UnknownControl");
unsigned long datumId = 0;
// Determine if this Data PDU contains a control message and collect it
for( int recordIndex = 1; datumId == 0 && 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());
}
#if 0
// This would just dump out the contents of all Data PDU.
// The value datatype would have to be known in order to decode it.
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());
DtDatabaseTableSP fixedTable = tables[myFixedDatumParameterTableIndex];
DtDatabaseTableSP varTable = tables[myVariableDatumParameterTableIndex];
int recordCount = dataPdu.numFixedFields();
int recordIndex = 0;
for( ; recordIndex < recordCount; ++recordIndex)
{
fixedTable->getColumn(myFixedDatumIdColumn->columnName())->addValue(dataPdu.fixedDatumId(recordIndex));
fixedTable->getColumn(myFixedDatumValueColumn->columnName())->addValue("unknown");
}
recordCount = dataPdu.numVarFields();
for( recordIndex = 0; recordIndex < recordCount; ++recordIndex)
{
if (data)
varTable->getColumn(myVariableDatumIdColumn->columnName())->addValue(dataPdu.varDatumId(recordIndex));
varTable->getColumn(myVariableDatumValueColumn->columnName())->addValue("unknown");
}
#endif
}
}
#endif

Document ID: Generated on Mon Jan 19 08:20:14 EST 2015 from SVN revision 149581
Copyright © 2005-2012 VT MÄK. All Rights Reserved (www.mak.com)