From c8f34d742033a3528638e5b6e5849ea6108a3848 Mon Sep 17 00:00:00 2001 From: Tomas Vrana Date: Wed, 22 Oct 2025 11:52:15 +0000 Subject: [PATCH 1/2] fieldClassifier: bugfix: output unirec did not have original data unirec fields data comming to plugin were not copied to output -> empty fields. This commit partial fixes this by allowing non array unirec members to by copied changelog: Bugfixes in . --- .../fieldClassifier/src/fieldClassifier.cpp | 130 ++++++++++++++++++ .../fieldClassifier/src/fieldClassifier.hpp | 5 + modules/fieldClassifier/src/main.cpp | 9 ++ .../fieldClassifier/src/plugins/plugin.hpp | 8 +- 4 files changed, 148 insertions(+), 4 deletions(-) diff --git a/modules/fieldClassifier/src/fieldClassifier.cpp b/modules/fieldClassifier/src/fieldClassifier.cpp index 0b4e2ac..c0d5cdd 100644 --- a/modules/fieldClassifier/src/fieldClassifier.cpp +++ b/modules/fieldClassifier/src/fieldClassifier.cpp @@ -281,6 +281,136 @@ void FieldClassifier::loadIP( + ex.what()); } } +void FieldClassifier::fillInputFieldsToOutput( + std::optional& input, + std::optional& output, + std::string& templateStr) +{ + // split template to vector by commas + std::vector templateFields; + size_t pos = 0; + std::string strCopy = templateStr; + if (templateStr.back() != ',') { + strCopy += ','; // Add a trailing comma to ensure the last field is processed + } + while ((pos = strCopy.find(',')) != std::string::npos) { + // Extract the field + std::string field = strCopy.substr(0, pos); + strCopy.erase(0, pos + 1); + if (!field.empty()) { // ignore empty fields + templateFields.push_back(field); + } + } + // for each field, get data from input and set to output + for (const auto& field : templateFields) { + // split field by space to get field name + size_t spacePos = field.find(' '); + if (spacePos == std::string::npos) { + throw std::runtime_error( + "FieldClassifier: Invalid Unirec field format in template: " + field); + } + std::string fieldName = field.substr(spacePos + 1); + std::string fieldType = field.substr(0, spacePos); + + auto fieldId = static_cast(ur_get_id_by_name(fieldName.c_str())); + if (fieldId == UR_E_INVALID_NAME) { + throw std::runtime_error("FieldClassifier: Invalid Unirec field name: " + fieldName); + } + try { + if (fieldType == "string") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint8") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint16") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint32") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint64") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "ipaddr") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int8") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int16") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int32") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int64") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "char") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "float") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "double") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "macaddr") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "time") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "bytes") { + // Nemea::UnirecArray const arr + // = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(arr, fieldId); + // TODO: implement + } else if (fieldType == "int8*") { + // const int8_t* value = input->getFieldAsType(fieldId); + // output->setFieldFromType((int8_t*) value, fieldId); + } else if (fieldType == "int16*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "int32*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "int64*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "uint8*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "uint16*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "uint32*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "uint64*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "time*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "float*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else if (fieldType == "double*") { + // auto value = input->getFieldAsUnirecArray(fieldId); + // output->setFieldFromUnirecArray(value, fieldId); + } else { + // throw std::runtime_error( + // "FieldClassifier: Unsupported Unirec field type: " + fieldType); + } + } catch (const std::exception& ex) { + throw std::runtime_error( + std::string("FieldClassifier: Unable to copy field '") + field + + "' from input to output Unirec record: " + ex.what()); + } + } +} void FieldClassifier::getDataFromPlugins(std::optional& unirecView) { diff --git a/modules/fieldClassifier/src/fieldClassifier.hpp b/modules/fieldClassifier/src/fieldClassifier.hpp index 5dc4ef3..7ed2f8d 100644 --- a/modules/fieldClassifier/src/fieldClassifier.hpp +++ b/modules/fieldClassifier/src/fieldClassifier.hpp @@ -76,6 +76,11 @@ class FieldClassifier { */ void handleParams(int argc, char** argv, argparse::ArgumentParser& parser); + void fillInputFieldsToOutput( + std::optional& input, + std::optional& output, + std::string& templateStr); + private: std::vector m_plugins = g_PLUGINS; diff --git a/modules/fieldClassifier/src/main.cpp b/modules/fieldClassifier/src/main.cpp index 31de888..4045d88 100644 --- a/modules/fieldClassifier/src/main.cpp +++ b/modules/fieldClassifier/src/main.cpp @@ -62,6 +62,15 @@ static void processNextRecord( throw std::runtime_error(std::string("Unable to create output Unirec record")); return; } + auto* templateDef = input.getTemplate(); + if (templateDef == nullptr) { + throw std::runtime_error(std::string("Unable to get template from trap input")); + } + + // convert template to string and append new fileds + std::string stringTemp = static_cast(ur_template_string(templateDef)); + + fieldClassifier.fillInputFieldsToOutput(inputUnirecView, unirecRecord, stringTemp); // populate Unirec record with data from modules try { diff --git a/modules/fieldClassifier/src/plugins/plugin.hpp b/modules/fieldClassifier/src/plugins/plugin.hpp index be8eef8..43e16d0 100644 --- a/modules/fieldClassifier/src/plugins/plugin.hpp +++ b/modules/fieldClassifier/src/plugins/plugin.hpp @@ -58,11 +58,11 @@ enum DataType : uint8_t { CHAR, FLOAT, DOUBLE, - // IPADDR, - // MACADDR, - // TIME, + IPADDR, + MACADDR, + TIME, STRING, - // BYTES + BYTES }; /** From 9ff04603d97d2ad21d3f0d7365099213c868b1b4 Mon Sep 17 00:00:00 2001 From: Tomas Vrana Date: Wed, 22 Oct 2025 12:30:45 +0000 Subject: [PATCH 2/2] fieldClassifier: bugfix: Adding support for unirecArrays changelog: Bugfixes in . --- .../fieldClassifier/src/fieldClassifier.cpp | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/modules/fieldClassifier/src/fieldClassifier.cpp b/modules/fieldClassifier/src/fieldClassifier.cpp index c0d5cdd..3125d90 100644 --- a/modules/fieldClassifier/src/fieldClassifier.cpp +++ b/modules/fieldClassifier/src/fieldClassifier.cpp @@ -285,6 +285,7 @@ void FieldClassifier::fillInputFieldsToOutput( std::optional& input, std::optional& output, std::string& templateStr) + { // split template to vector by commas std::vector templateFields; @@ -363,47 +364,53 @@ void FieldClassifier::fillInputFieldsToOutput( auto value = input->getFieldAsType(fieldId); output->setFieldFromType(value, fieldId); } else if (fieldType == "bytes") { - // Nemea::UnirecArray const arr - // = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(arr, fieldId); - // TODO: implement + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "int8*") { - // const int8_t* value = input->getFieldAsType(fieldId); - // output->setFieldFromType((int8_t*) value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "int16*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "int32*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "int64*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "uint8*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "uint16*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "uint32*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "uint64*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); - } else if (fieldType == "time*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "float*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else if (fieldType == "double*") { - // auto value = input->getFieldAsUnirecArray(fieldId); - // output->setFieldFromUnirecArray(value, fieldId); + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); } else { - // throw std::runtime_error( - // "FieldClassifier: Unsupported Unirec field type: " + fieldType); + throw std::runtime_error( + "FieldClassifier: Unsupported Unirec field type in template: " + fieldType); } + } catch (const std::exception& ex) { throw std::runtime_error( std::string("FieldClassifier: Unable to copy field '") + field