#include "demo_can_decoder.h"
#include <cstring>
#include <string>
#include <map>
ADTF_PLUGIN_VERSION("Demo CAN Decoder",
devicetb,
DEVICETB_VERSION_MAJOR,
DEVICETB_VERSION_MINOR,
DEVICETB_VERSION_PATCH,
cCAN2DDLFilter)
namespace {
const std::map<std::string, std::string> mapping{
{ "ECU2_Full.ECU2_Signal8_16","ECU2_Signal8_16" },
{ "ECU2_Full.ECU2_Signal7_4","ECU2_Signal7_4" },
{ "ECU2_Full.ECU2_Signal6_4","ECU2_Signal6_4" },
{ "ECU2_Full.ECU2_Signal5_6","ECU2_Signal5_6" },
{ "ECU2_Full.ECU2_Signal4_10","ECU2_Signal4_10" },
{ "ECU2_Full.ECU2_Signal3_8","ECU2_Signal3_8" },
{ "ECU2_Full.ECU2_Signal2_6","ECU2_Signal2_6" },
{ "ECU2_Full.ECU2_Signal1_10","ECU2_Signal1_10" },
};
}
cCAN2DDLFilter::cCAN2DDLFilter():
m_pWriter(CreateOutputPin<mediadescription::encoding_sample_writer<>>("output_ddl", mediadescription::description<output_ddl>()))
{
SetDescription("input_can", "The CAN sample stream to decode.");
SetDescription("output_ddl", "The decoded content of the CAN sample stream.");
m_nChannelID.SetDescription("Channel-ID for the desired can database, made available by can service.");
m_nChannelID.SetValidRange(CAN_CHANNEL_MIN, CAN_CHANNEL_MAX);
RegisterPropertyVariable("ChannelID", m_nChannelID);
SetDescription("Demo filter for decoding CAN samples into previous specified signals.");
SetHelpLink("$(ADTF_DEVICE_TOOLBOX_DIR)/doc/adtf_device_toolbox_html/page_example_source_can_config_decoder.html");
}
tResult cCAN2DDLFilter::Init(filter::cFilter::tInitStage eStage)
{
if (filter::cFilter::tInitStage::StageNormal == eStage)
{
RETURN_IF_FAILED(_runtime->GetObject(m_pCANSupport));
RETURN_IF_FAILED(m_pCANSupport->CreateCoder(m_pDecoder));
}
RETURN_NOERROR;
}
tResult cCAN2DDLFilter::ProcessInput(streaming::ISampleReader* ,
const ucom::iobject_ptr<const streaming::ISample>& pSample)
{
streaming::sample_data<tCANData> pData(pSample);
m_pDecoder->Begin(pData.GetDataPtr(),
sizeof(
tCANData));
auto oGeneratedData = m_pWriter->MakeSample(pData.GetTimeNs());
tChannelID nChannel = static_cast<tChannelID>(*m_nChannelID);
tMessageID nCANMessageID;
tBool bExtended = tFalse;
if (IS_OK(m_pDecoder->GetMessageInfo(&nChannel, &nCANMessageID, &bExtended)))
{
ucom::object_ptr<ICANDatabase> pDatabase;
RETURN_IF_FAILED(m_pDecoder->GetDatabase(nChannel, pDatabase));
if (IS_OK(pDatabase->GetMessageInfo(nCANMessageID, bExtended, &pInfo)))
{
if (util::cString("ECU2_Full").Compare(pInfo->strMessageName) == 0)
{
for (const auto& it : mapping)
{
util::cString sgnNm = it.first.c_str();
tSignalID nSignalID;
pDatabase->GetSignalID(sgnNm, &nSignalID);
if (IS_OK(m_pDecoder->GetSignalValue(nSignalID, &sSignalValue)))
{
util::cVariant oValue;
auto oElement = oGeneratedData.GetElement(it.second);
switch (sSignalValue.nTypeTag)
{
case tSignalValue::TAG_RAW_VALUE:
oElement.setValue(sSignalValue.n64RawValue);
break;
case tSignalValue::TAG_FLOAT64:
oElement.setValue(sSignalValue.f64Value);
break;
case tSignalValue::TAG_UINT64:
oElement.setValue(sSignalValue.nui64Value);
break;
case tSignalValue::TAG_INT64:
oElement.setValue(sSignalValue.ni64Value);
break;
case tSignalValue::TAG_UINT32:
oElement.setValue(sSignalValue.nui32Value);
break;
case tSignalValue::TAG_INT32:
oElement.setValue(sSignalValue.ni32Value);
break;
case tSignalValue::TAG_FLOAT32:
oElement.setValue(sSignalValue.f32Value);
break;
default:
break;
}
}
}
m_pWriter->Write(oGeneratedData.Release());
}
}
}
return m_pDecoder->End();
}
Copyright 2024 CARIAD SE.
Namespace for CAN in ADTF-Devicetoolbox.
axle::tMessageInfo tMessageInfo
axle::tSignalValue tSignalValue
axle::tCANData tCANData
The CAN data structure is used by CAN MediaSamples use following code within your filter:
axle::stream_meta_type_can stream_meta_type_can
Definition of Stream Meta Type CAN Messages.