/** * @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 "JAMessageGAM.h" #include "MessageI.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; } } JAMessageGAM::JAMessageGAM() { inputSignals = NULL_PTR(void **); inputSignalTypes = NULL_PTR(MARTe::TypeDescriptor *); operation = And; needsReset = false; expectedValuesInt = NULL_PTR(MARTe::uint64 *); expectedValuesFloat = NULL_PTR(MARTe::float64 *); intValuesCount = 0u; floatValuesCount = 0u; comparators = NULL_PTR(ComparisonMode *); } JAMessageGAM::~JAMessageGAM() { if (inputSignals != NULL_PTR(void **)) { delete[] inputSignals; } if (inputSignalTypes != NULL_PTR(MARTe::TypeDescriptor *)) { delete[] inputSignalTypes; } if (expectedValuesInt != NULL_PTR(MARTe::uint64 *)) { delete[] expectedValuesInt; } if (expectedValuesFloat != NULL_PTR(MARTe::float64 *)) { delete[] expectedValuesFloat; } if (comparators != NULL_PTR(ComparisonMode *)) { delete[] comparators; } } bool JAMessageGAM::Initialise(MARTe::StructuredDataI & data) { using namespace MARTe; bool ok = GAM::Initialise(data); if (ok) { // Read expected integer values. AnyType valuesArray = data.GetType("ExpectedIntValues"); bool intValuesProvided = (valuesArray.GetDataPointer() != NULL); if (intValuesProvided) { intValuesCount = valuesArray.GetNumberOfElements(0u); } if (intValuesProvided) { expectedValuesInt = new uint64[intValuesCount]; Vector valuesVector(expectedValuesInt, intValuesCount); ok = (data.Read("ExpectedIntValues", valuesVector)); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "Failed to read ExpectedIntValues."); return ok; } } // Read expected float values. valuesArray = data.GetType("ExpectedFloatValues"); bool floatValuesProvided = (valuesArray.GetDataPointer() != NULL); if (floatValuesProvided) { floatValuesCount = valuesArray.GetNumberOfElements(0u); } if (floatValuesProvided) { expectedValuesFloat = new float64[floatValuesCount]; Vector valuesVector(expectedValuesFloat, floatValuesCount); ok = (data.Read("ExpectedFloatValues", valuesVector)); if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "Failed to read ExpectedFloatValues."); return ok; } } ok = (floatValuesCount + intValuesCount) > 0u; if (!ok) { REPORT_ERROR(ErrorManagement::ParametersError, "ExpectedFloatValues and or ExpectedIntValues shall be defined."); } } if (ok) { // Read comparators. AnyType comparatorsArray = data.GetType("Comparators"); if (comparatorsArray.GetDataPointer() != NULL) { uint32 count = comparatorsArray.GetNumberOfElements(0u); ok = count == (intValuesCount + floatValuesCount); if (ok) { comparators = new ComparisonMode[count]; StreamString* comp = new StreamString[count]; Vector compVector(comp, count); ok = (data.Read("Comparators", compVector)); if (ok) { for (uint32 i = 0; i < count; ++i) { if (comp[i] == "EQUALS") { comparators[i] = Equals; } else if (comp[i] == "NOT") { comparators[i] = Not; } else if (comp[i] == "GREATER") { comparators[i] = Greater; } else if (comp[i] == "EQUALS_OR_GREATER") { comparators[i] = EqualsOrGreater; } else if (comp[i] == "LESS") { comparators[i] = Less; } else if (comp[i] == "EQUALS_OR_LESS") { comparators[i] = EqualsOrLess; } else { ok = false; REPORT_ERROR(ErrorManagement::ParametersError, "Comparator %s is not defined.", comp[i].Buffer()); } } } } else { REPORT_ERROR(ErrorManagement::ParametersError, "Expected values and operators shall have the same " "number of elements."); } } else { uint32 count = intValuesCount + floatValuesCount; if (ok) { // Create default comparators (equals) when they aren't provided in the configuration. comparators = new ComparisonMode[count]; for (uint32 i = 0; i < count; ++i) { comparators[i] = Equals; } } else { REPORT_ERROR(ErrorManagement::ParametersError, "Expected values and operators shall have the same " "number of elements."); } } } 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"); } } return ok; } bool JAMessageGAM::Setup() { using namespace MARTe; bool ok = numberOfInputSignals == (intValuesCount + floatValuesCount); if (ok) { 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"); } } else { REPORT_ERROR(ErrorManagement::ParametersError, "Number of input signals shall be the same as " "number of expected values."); } 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], inputSignals[inputPortIndex], expectedValuesInt[intValueIndex]); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == SignedInteger32Bit) { ret = ::Compare(comparators[inputPortIndex], inputSignals[inputPortIndex], expectedValuesInt[intValueIndex]); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == UnsignedInteger16Bit) { ret = ::Compare(comparators[inputPortIndex], inputSignals[inputPortIndex], expectedValuesInt[intValueIndex]); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == SignedInteger16Bit) { ret = ::Compare(comparators[inputPortIndex], inputSignals[inputPortIndex], expectedValuesInt[intValueIndex]); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == UnsignedInteger8Bit) { ret = ::Compare(comparators[inputPortIndex], inputSignals[inputPortIndex], expectedValuesInt[intValueIndex]); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == SignedInteger8Bit) { ret = ::Compare(comparators[inputPortIndex], inputSignals[inputPortIndex], expectedValuesInt[intValueIndex]); ++intValueIndex; } else if (inputSignalTypes[inputPortIndex] == Float64Bit) { ret = ::Compare(comparators[inputPortIndex], inputSignals[inputPortIndex], expectedValuesFloat[floatValueIndex]); ++floatValueIndex; } else { ret = ::Compare(comparators[inputPortIndex], inputSignals[inputPortIndex], expectedValuesFloat[floatValueIndex]); ++floatValueIndex; } return ret; } CLASS_REGISTER(JAMessageGAM, "1.0")