/** * @file JAMessageGAM.cpp * @brief Source file for class JAMessageGAM * @date Jan, 2019 * @author rhari * * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and * the Development of Fusion Energy ('Fusion for Energy'). * Licensed under the EUPL, Version 1.1 or - as soon they will be approved * by the European Commission - subsequent versions of the EUPL (the "Licence") * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl * * @warning Unless required by applicable law or agreed to in writing, * software distributed under the Licence is distributed on an "AS IS" * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the Licence permissions and limitations under the Licence. * @details This source file contains the definition of all the methods for * the class JAMessageGAM (public, protected, and private). Be aware that some * methods, such as those inline could be defined on the header file, instead. */ /*---------------------------------------------------------------------------*/ /* Standard header includes */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Project header includes */ /*---------------------------------------------------------------------------*/ #include "AdvancedErrorManagement.h" #include "Architecture/x86_gcc/CompilerTypes.h" #include "ErrorType.h" #include "JAMessageGAM.h" #include "MessageI.h" #include "StreamString.h" #include "TypeDescriptor.h" /*---------------------------------------------------------------------------*/ /* Static definitions */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Method definitions */ /*---------------------------------------------------------------------------*/ template bool Compare(JAMessageGAM::ComparisonMode comparator, void *inputSignal, U expectedValue) { switch (comparator) { case JAMessageGAM::Equals: return *static_cast(inputSignal) == expectedValue; case JAMessageGAM::Not: return *static_cast(inputSignal) != expectedValue; case JAMessageGAM::Greater: return *static_cast(inputSignal) > expectedValue; case JAMessageGAM::EqualsOrGreater: return *static_cast(inputSignal) >= expectedValue; case JAMessageGAM::Less: return *static_cast(inputSignal) < expectedValue; default: // case EqualsOrLess: return *static_cast(inputSignal) <= expectedValue; } } bool parse_comparator(const MARTe::StreamString &str, JAMessageGAM::ComparisonMode &op) { if (str == "EQUALS") { op = JAMessageGAM::Equals; return true; } if (str == "NOT") { op = JAMessageGAM::Not; return true; } if (str == "GREATER") { op = JAMessageGAM::Greater; return true; } if (str == "EQUALS_OR_GREATER") { op = JAMessageGAM::EqualsOrGreater; return true; } if (str == "LESS") { op = JAMessageGAM::Less; return true; } if (str == "EQUALS_OR_LESS") { op = JAMessageGAM::EqualsOrLess; return true; } return false; } bool is_int(const MARTe::TypeDescriptor &td) { return (td == MARTe::UnsignedInteger32Bit) || (td == MARTe::SignedInteger32Bit) || (td == MARTe::UnsignedInteger16Bit) || (td == MARTe::SignedInteger16Bit) || (td == MARTe::UnsignedInteger8Bit) || (td == MARTe::SignedInteger8Bit); } bool is_float(const MARTe::TypeDescriptor &td) { return (td == MARTe::Float32Bit) || (td == MARTe::Float64Bit); } JAMessageGAM::JAMessageGAM() { inputSignals = NULL_PTR(void **); inputSignalTypes = NULL_PTR(MARTe::TypeDescriptor *); comparators = NULL_PTR(comparator_t *); operation = And; needsReset = false; } JAMessageGAM::~JAMessageGAM() { if (inputSignals != NULL_PTR(void **)) { delete[] inputSignals; } if (inputSignalTypes != NULL_PTR(MARTe::TypeDescriptor *)) { delete[] inputSignalTypes; } if (comparators != NULL_PTR(comparator_t *)) { delete[] comparators; } } bool JAMessageGAM::Initialise(MARTe::StructuredDataI &data) { using namespace MARTe; bool ok = GAM::Initialise(data); if (ok) { MARTe::StreamString operationStr; if (data.Read("Operation", operationStr)) { if (operationStr == "AND") { operation = And; } else if (operationStr == "OR") { operation = Or; } else if (operationStr == "NOR") { operation = Nor; } else if (operationStr == "XOR") { operation = Xor; } else { ok = false; REPORT_ERROR(ErrorManagement::ParametersError, "Operation %s is not defined", operationStr.Buffer()); } } } if (ok) { ok = (Size() == 1); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "A Message object shall be added to this container"); } } if (ok) { eventMsg = Get(0); ok = (eventMsg.IsValid()); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "A valid Message shall be added to this container"); } } if (ok) { ok = data.MoveRelative("InputSignals"); uint32 level = 0; if (ok) { level++; uint32 n_inputs = data.GetNumberOfChildren(); comparators = new comparator_t[n_inputs]; StreamString buffer; TypeDescriptor td; for (uint32 i = 0; ok && i < n_inputs; i++) { ok = data.MoveToChild(i); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "Impossible to move to InputSignals[%lu]", i); break; } level++; ok = data.Read("Type", buffer); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "Missing mandatory field Type from InputSignals[%lu]", i); break; } td = TypeDescriptor::GetTypeDescriptorFromTypeName(buffer.Buffer()); ok = (td != InvalidType) && (is_float(td) || is_int(td)); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "Wrong value for field Type from InputSignals[%lu]", i); break; } ok = data.Read("Comparator", buffer); if (!ok) { REPORT_ERROR( ErrorManagement::ParametersError, "Missing mandatory field Comparator from InputSignals[%lu]", i); break; } ok = parse_comparator(buffer, comparators[i].comparator); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "Non Valid Comparator `%s` from InputSignals[%lu]", buffer, i); break; } if (is_int(td)) { ok = data.Read("Value", comparators[i].value.i64); if (!ok) { REPORT_ERROR( ErrorManagement::ParametersError, "Missing field Value (expecting int) from InputSignals[%lu]", i); break; } } else { ok = data.Read("Value", comparators[i].value.f64); if (!ok) { REPORT_ERROR( ErrorManagement::ParametersError, "Missing field Value (expecting float) from InputSignals[%lu]", i); break; } } if (data.MoveToAncestor(1)) { level--; } } data.MoveToAncestor(level); } else { REPORT_ERROR(ErrorManagement::ParametersError, "Impossible to move to InputSignals"); } } return ok; } bool JAMessageGAM::Setup() { using namespace MARTe; bool ok = numberOfInputSignals > 0u; if (ok) { inputSignals = new void *[numberOfInputSignals]; uint32 i; for (i = 0u; i < numberOfInputSignals; i++) { inputSignals[i] = GetInputSignalMemory(i); } } else { REPORT_ERROR(ErrorManagement::ParametersError, "At least one input signal shall be defined"); } if (ok) { inputSignalTypes = new TypeDescriptor[numberOfInputSignals]; uint32 i; for (i = 0u; (i < numberOfInputSignals) && (ok); i++) { TypeDescriptor inputType = GetSignalType(InputSignals, i); inputSignalTypes[i] = inputType; ok = (inputType == UnsignedInteger32Bit) || (inputType == SignedInteger32Bit) || (inputType == UnsignedInteger16Bit) || (inputType == SignedInteger16Bit) || (inputType == UnsignedInteger8Bit) || (inputType == SignedInteger8Bit) || (inputType == Float64Bit) || (inputType == Float32Bit); if (!ok) { StreamString signalName; (void)GetSignalName(InputSignals, i, signalName); REPORT_ERROR(ErrorManagement::ParametersError, "Signal %s shall be defined as 32/16/8 bit " "signed/unsigned integer " "or as 64/32 float.", signalName.Buffer()); } } } return ok; } bool JAMessageGAM::PrepareNextState(const MARTe::char8 *const currentStateName, const MARTe::char8 *const nextStateName) { needsReset = false; return true; } bool JAMessageGAM::Execute() { using namespace MARTe; bool ok = true; bool eventDetected = false; uint32 inputPortIndex = 0; uint32 intIndex = 0; uint32 floatIndex = 0; if (operation == Or) { for (inputPortIndex = 0; (inputPortIndex < numberOfInputSignals) && (!eventDetected); inputPortIndex++) { eventDetected = Compare(inputPortIndex, floatIndex, intIndex); } } else if (operation == Nor) { for (inputPortIndex = 0; (inputPortIndex < numberOfInputSignals) && (!eventDetected); inputPortIndex++) { eventDetected = Compare(inputPortIndex, floatIndex, intIndex); } eventDetected = !eventDetected; } else if (operation == And) { eventDetected = Compare(0, floatIndex, intIndex); for (inputPortIndex = 1; (inputPortIndex < numberOfInputSignals); inputPortIndex++) { eventDetected = Compare(inputPortIndex, floatIndex, intIndex); } } else if (operation == Xor) { uint32 eventDetectedUInt32 = Compare(inputPortIndex, floatIndex, intIndex); for (inputPortIndex = 1; (inputPortIndex < numberOfInputSignals); inputPortIndex++) { eventDetectedUInt32 ^= Compare(inputPortIndex, floatIndex, intIndex); } eventDetected = (eventDetectedUInt32 == 1u); } if (eventDetected) { if (!needsReset) { ok = (MessageI::SendMessage(eventMsg, this) == ErrorManagement::NoError); needsReset = true; } } return ok; } bool JAMessageGAM::Compare(MARTe::uint32 inputPortIndex, MARTe::uint32 &floatValueIndex, MARTe::uint32 &intValueIndex) { using namespace MARTe; bool ret = false; if (inputSignalTypes[inputPortIndex] == UnsignedInteger32Bit) { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.i64); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == SignedInteger32Bit) { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.i64); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == UnsignedInteger16Bit) { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.i64); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == SignedInteger16Bit) { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.i64); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == UnsignedInteger8Bit) { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.i64); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == SignedInteger8Bit) { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.i64); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == Float64Bit) { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.f64); ++floatValueIndex; } else { ret = ::Compare(comparators[inputPortIndex].comparator, inputSignals[inputPortIndex], comparators[inputPortIndex].value.f64); ++floatValueIndex; } return ret; } CLASS_REGISTER(JAMessageGAM, "1.0")