Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Monitoring support for OPC UA Device Management #52

Merged
merged 4 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 159 additions & 50 deletions src/stdfblib/ita/OPCUA_MGR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,31 @@ char OPCUA_MGR::smDeleteConnArg2Description[] = "{SubApp.FbName.PortName}";
char OPCUA_MGR::smDeleteConnAttrDisplayName[] = "Delete Connection";
char OPCUA_MGR::smDeleteConnAttrDescription[] = "Delete Connection";

#ifdef FORTE_SUPPORT_MONITORING

/* Add Watch */
char OPCUA_MGR::smAddWatchMethodName[] = "addWatch";
char OPCUA_MGR::smAddWatchArgName[] = "FB Port";
char OPCUA_MGR::smAddWatchArgDescription[] = "Fully qualified name of FB Port";
char OPCUA_MGR::smAddWatchAttrDisplayName[] = "Add Watch";
char OPCUA_MGR::smAddWatchAttrDescription[] = "Add Watch";

/* Read Watches */
char OPCUA_MGR::smReadWatchesMethodName[] = "readWatches";
char OPCUA_MGR::smReadWatchesOutArgName[] = "Response";
char OPCUA_MGR::smReadWatchesOutArgDescription[] = "Read Response";
char OPCUA_MGR::smReadWatchesDisplayName[] = "Read Watches";
char OPCUA_MGR::smReadWatchesDescription[] = "Read Watches";

/* Remove Watch */
char OPCUA_MGR::smRemoveWatchMethodName[] = "removeWatch";
char OPCUA_MGR::smRemoveWatchArgName[] = "FB Port";
char OPCUA_MGR::smRemoveWatchArgDescription[] = "Fully qualified name of FB Port";
char OPCUA_MGR::smRemoveWatchAttrDisplayName[] = "Remove Watch";
char OPCUA_MGR::smRemoveWatchAttrDescription[] = "Remove Watch";

#endif // FORTE_SUPPORT_MONITORING

/* Initialize UA Status Codes */
const std::map<EMGMResponse, UA_StatusCode> OPCUA_MGR::scResponseMap = {
{EMGMResponse::Ready, UA_STATUSCODE_GOOD},
Expand Down Expand Up @@ -235,6 +260,9 @@ EMGMResponse OPCUA_MGR::createIEC61499MgmtObject(UA_Server* paServer) {
if (addKillDeviceMethod(paServer) != EMGMResponse::Ready) return eRetVal;
if (addKillResourceMethod(paServer) != EMGMResponse::Ready) return eRetVal;
if (addDeleteResourceMethod(paServer) != EMGMResponse::Ready) return eRetVal;
#ifdef FORTE_SUPPORT_MONITORING
if (addReadWatchesMethod(paServer) != EMGMResponse::Ready) return eRetVal;
#endif // FORTE_SUPPORT_MONITORING
return addMgmtObjectInstance();
}

Expand Down Expand Up @@ -284,6 +312,10 @@ EMGMResponse OPCUA_MGR::createIEC61499ResourceObjectType(UA_Server* paServer) {
if (addKillFBMethod(paServer) != EMGMResponse::Ready) return eRetVal;
if (addDeleteFBMethod(paServer) != EMGMResponse::Ready) return eRetVal;
if (addDeleteConnectionMethod(paServer) != EMGMResponse::Ready) return eRetVal;
#ifdef FORTE_SUPPORT_MONITORING
if (addAddWatchMethod(paServer) != EMGMResponse::Ready) return eRetVal;
if (addRemoveWatchMethod(paServer) != EMGMResponse::Ready) return eRetVal;
#endif // FORTE_SUPPORT_MONITORING
return EMGMResponse::Ready;
}

Expand Down Expand Up @@ -354,8 +386,8 @@ UA_StatusCode OPCUA_MGR::onCreateResource(UA_Server*,
if (!methodContext) {
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}
std::string resourceName = getInputValue(*static_cast<UA_String*>(input[0].data));
std::string resType = getInputValue(*static_cast<UA_String*>(input[1].data));
const std::string resourceName(getInputValue(*static_cast<UA_String*>(input[0].data)));
const std::string resType(getInputValue(*static_cast<UA_String*>(input[1].data)));

OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::CreateFBInstance, CStringDictionary::scmInvalidStringId, nullptr, resourceName.c_str(), resType.c_str());
Expand Down Expand Up @@ -400,10 +432,8 @@ UA_StatusCode OPCUA_MGR::onCreateFB(UA_Server*,
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[0].data));
std::string fbTypeStr;
fbTypeStr = getInputValue(*static_cast<UA_String*>(input[1].data));
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
const std::string fbTypeStr(getInputValue(*static_cast<UA_String*>(input[1].data)));

std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);
Expand Down Expand Up @@ -435,10 +465,8 @@ UA_StatusCode OPCUA_MGR::onCreateConnection(UA_Server*,
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string source;
source = getInputValue(*static_cast<UA_String*>(input[0].data));
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[1].data));
const std::string source(getInputValue(*static_cast<UA_String*>(input[0].data)));
const std::string destination(getInputValue(*static_cast<UA_String*>(input[1].data)));

std::vector<std::string> sourceFullName;
std::vector<std::string> destinationFullName;
Expand Down Expand Up @@ -468,7 +496,7 @@ UA_StatusCode OPCUA_MGR::onWriteDevice(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string writeValue = getInputValue(*static_cast<UA_String*>(input[0].data));
const std::string writeValue(getInputValue(*static_cast<UA_String*>(input[0].data)));

OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::Write, CStringDictionary::scmInvalidStringId, writeValue.c_str(), nullptr, nullptr);
Expand All @@ -495,8 +523,8 @@ UA_StatusCode OPCUA_MGR::onWriteResource(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string resourceName = getInputValue(*static_cast<UA_String*>(input[0].data));
std::string writeValue = getInputValue(*static_cast<UA_String*>(input[1].data));
const std::string resourceName(getInputValue(*static_cast<UA_String*>(input[0].data)));
const std::string writeValue(getInputValue(*static_cast<UA_String*>(input[1].data)));

OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::Write, CStringDictionary::getInstance().insert(resourceName.c_str()), writeValue.c_str(), nullptr, nullptr);
Expand Down Expand Up @@ -525,9 +553,8 @@ UA_StatusCode OPCUA_MGR::onWriteFB(UA_Server*,
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[0].data));
std::string writeValue = getInputValue(*static_cast<UA_String*>(input[1].data));
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
const std::string writeValue(getInputValue(*static_cast<UA_String*>(input[1].data)));
std::vector<std::string> writeDestination;
parseDestinationName(destination, writeDestination);

Expand Down Expand Up @@ -577,8 +604,7 @@ UA_StatusCode OPCUA_MGR::onStartResource(UA_Server*,
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
/* Resource Name */
std::string resourceName = getInputValue(*static_cast<UA_String*>(input[0].data));
const std::string resourceName(getInputValue(*static_cast<UA_String*>(input[0].data)));
OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::Start, CStringDictionary::getInstance().insert(resourceName.c_str()), nullptr, nullptr, nullptr);
eRetVal = uaMGR->mUaDevice.executeMGMCommand(uaMGR->mCommand);
Expand All @@ -601,9 +627,7 @@ UA_StatusCode OPCUA_MGR::onStartFB(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[0].data));
/* e.g. SubApp1.FB1*/
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);

Expand Down Expand Up @@ -653,7 +677,7 @@ UA_StatusCode OPCUA_MGR::onStopResource(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string resourceName = getInputValue(*static_cast<UA_String*>(input[0].data));
const std::string resourceName(getInputValue(*static_cast<UA_String*>(input[0].data)));
OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::Stop, CStringDictionary::scmInvalidStringId, nullptr, resourceName.c_str(), nullptr);
eRetVal = uaMGR->mUaDevice.executeMGMCommand(uaMGR->mCommand);
Expand All @@ -678,9 +702,7 @@ UA_StatusCode OPCUA_MGR::onStopFB(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[0].data));
/* e.g. SubApp1.FB1*/
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);

Expand Down Expand Up @@ -730,7 +752,7 @@ UA_StatusCode OPCUA_MGR::onResetResource(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string resourceName = getInputValue(*static_cast<UA_String*>(input[0].data));
const std::string resourceName(getInputValue(*static_cast<UA_String*>(input[0].data)));
OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::Reset, CStringDictionary::scmInvalidStringId, nullptr, resourceName.c_str(), nullptr);
eRetVal = uaMGR->mUaDevice.executeMGMCommand(uaMGR->mCommand);
Expand All @@ -755,9 +777,7 @@ UA_StatusCode OPCUA_MGR::onResetFB(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[0].data));
/* e.g. SubApp1.FB1*/
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);

Expand Down Expand Up @@ -807,7 +827,7 @@ UA_StatusCode OPCUA_MGR::onKillResource(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string resourceName = getInputValue(*static_cast<UA_String*>(input[0].data));
const std::string resourceName(getInputValue(*static_cast<UA_String*>(input[0].data)));
OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::Kill, CStringDictionary::scmInvalidStringId, nullptr, resourceName.c_str(), nullptr);
eRetVal = uaMGR->mUaDevice.executeMGMCommand(uaMGR->mCommand);
Expand All @@ -832,9 +852,7 @@ UA_StatusCode OPCUA_MGR::onKillFB(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[0].data));
/* e.g. SubApp1.FB1*/
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);

Expand Down Expand Up @@ -865,8 +883,7 @@ UA_StatusCode OPCUA_MGR::onDeleteResource(UA_Server*,
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
/* Resource Name */
std::string resourceName = getInputValue(*static_cast<UA_String*>(input[0].data));
const std::string resourceName(getInputValue(*static_cast<UA_String*>(input[0].data)));

OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::DeleteFBInstance, CStringDictionary::scmInvalidStringId, nullptr, resourceName.c_str(), nullptr);
Expand Down Expand Up @@ -898,9 +915,7 @@ UA_StatusCode OPCUA_MGR::onDeleteFB(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[0].data));
/* e.g. SubApp1.FB1*/
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);

Expand Down Expand Up @@ -931,10 +946,8 @@ UA_StatusCode OPCUA_MGR::onDeleteConnection(UA_Server*,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
std::string source;
source = getInputValue(*static_cast<UA_String*>(input[0].data));
std::string destination;
destination = getInputValue(*static_cast<UA_String*>(input[1].data));
const std::string source(getInputValue(*static_cast<UA_String*>(input[0].data)));
const std::string destination(getInputValue(*static_cast<UA_String*>(input[1].data)));
std::vector<std::string> sourceFullName;
std::vector<std::string> destinationFullName;
parseDestinationName(source, sourceFullName);
Expand All @@ -949,6 +962,99 @@ UA_StatusCode OPCUA_MGR::onDeleteConnection(UA_Server*,
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}

/* FORTE Monitoring */
#ifdef FORTE_SUPPORT_MONITORING

EMGMResponse OPCUA_MGR::addAddWatchMethod(UA_Server* paServer) {
UA_Argument inputArgument;
initArgument(inputArgument, UA_TYPES_STRING, smAddWatchArgName, smAddWatchArgDescription);

UA_MethodAttributes addWatchAttr = createAttribute(smAddWatchAttrDisplayName, smAddWatchAttrDescription);
return addMethodNode(paServer, smAddWatchMethodName, mResourceTypeId, addWatchAttr, &inputArgument, 1, nullptr, 0, &onAddWatch);
}

UA_StatusCode OPCUA_MGR::onAddWatch(UA_Server*,
const UA_NodeId*, void*,
const UA_NodeId*, void* methodContext,
const UA_NodeId*, void* objectContext,
size_t, const UA_Variant* input,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);

const char* resourceName = static_cast<const char*>(objectContext);
OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::MonitoringAddWatch, CStringDictionary::getInstance().insert(resourceName), nullptr, fullFbName);
eRetVal = uaMGR->mUaDevice.executeMGMCommand(uaMGR->mCommand);
return scResponseMap.find(eRetVal)->second;
}
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}

EMGMResponse OPCUA_MGR::addReadWatchesMethod(UA_Server* paServer) {
UA_Argument outputArgument;
initArgument(outputArgument, UA_TYPES_STRING, smReadWatchesOutArgName, smReadWatchesOutArgDescription);
UA_MethodAttributes readWatchesAttr = createAttribute(smReadWatchesDisplayName, smReadWatchesDescription);
return addMethodNode(paServer, smReadWatchesMethodName, mMgmtTypeId, readWatchesAttr, nullptr, 0, &outputArgument, 1, &onReadWatches);
}

UA_StatusCode OPCUA_MGR::onReadWatches(UA_Server*,
const UA_NodeId*, void*,
const UA_NodeId*, void* methodContext,
const UA_NodeId*, void*,
size_t, const UA_Variant*,
size_t, UA_Variant* output) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::MonitoringReadWatches, CStringDictionary::scmInvalidStringId, nullptr, nullptr, nullptr);
eRetVal = uaMGR->mUaDevice.executeMGMCommand(uaMGR->mCommand);
int status = scResponseMap.find(eRetVal)->second;
if (status != UA_STATUSCODE_GOOD) {
return status;
}
UA_String uaResp = UA_String_fromChars(uaMGR->mCommand.mMonitorResponse.c_str());
status = UA_Variant_setScalarCopy(output, &uaResp, &UA_TYPES[UA_TYPES_STRING]);
UA_String_clear(&uaResp);
return status;
}
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}

EMGMResponse OPCUA_MGR::addRemoveWatchMethod(UA_Server* paServer) {
UA_Argument inputArgument;
initArgument(inputArgument, UA_TYPES_STRING, smRemoveWatchArgName, smRemoveWatchArgDescription);

UA_MethodAttributes removeWatchAttr = createAttribute(smRemoveWatchAttrDisplayName, smRemoveWatchAttrDescription);
return addMethodNode(paServer, smRemoveWatchMethodName, mResourceTypeId, removeWatchAttr, &inputArgument, 1, nullptr, 0, &onRemoveWatch);
}

UA_StatusCode OPCUA_MGR::onRemoveWatch(UA_Server*,
const UA_NodeId*, void*,
const UA_NodeId*, void* methodContext,
const UA_NodeId*, void* objectContext,
size_t, const UA_Variant* input,
size_t, UA_Variant*) {
if (methodContext != nullptr) {
EMGMResponse eRetVal = EMGMResponse::UnsupportedType;
const std::string destination(getInputValue(*static_cast<UA_String*>(input[0].data)));
std::vector<std::string> fullFbName;
parseDestinationName(destination, fullFbName);

const char* resourceName = static_cast<const char*>(objectContext);
OPCUA_MGR* uaMGR = static_cast<OPCUA_MGR*>(methodContext);
uaMGR->setMGMCommand(EMGMCommandType::MonitoringRemoveWatch, CStringDictionary::getInstance().insert(resourceName), nullptr, fullFbName);
eRetVal = uaMGR->mUaDevice.executeMGMCommand(uaMGR->mCommand);
return scResponseMap.find(eRetVal)->second;
}
return UA_STATUSCODE_BADUNKNOWNRESPONSE;
}

#endif // FORTE_SUPPORT_MONITORING

/* Helpers */

EMGMResponse OPCUA_MGR::addMethodNode(UA_Server* paServer, char* paMethodNodeName, UA_NodeId paParentNodeId, UA_MethodAttributes paAttr,
Expand Down Expand Up @@ -1001,7 +1107,9 @@ void OPCUA_MGR::clearMGMCommand() {
mCommand.mFirstParam.clear();
mCommand.mSecondParam.clear();
mCommand.mAdditionalParams.clear();
#ifdef FORTE_SUPPORT_MONITORING
mCommand.mMonitorResponse.clear();
#endif // FORTE_SUPPORT_MONITORING
}

void OPCUA_MGR::setMGMCommand(EMGMCommandType paCMD, CStringDictionary::TStringId paDestination,
Expand All @@ -1016,7 +1124,7 @@ void OPCUA_MGR::setMGMCommand(EMGMCommandType paCMD, CStringDictionary::TStringI
mCommand.mSecondParam.pushBack(CStringDictionary::getInstance().insert(paSecondParam));
}
if (paAdditionalParams != nullptr) {
mCommand.mAdditionalParams.fromString(paAdditionalParams);
mCommand.mAdditionalParams = CIEC_STRING(paAdditionalParams);
}
}

Expand All @@ -1037,7 +1145,7 @@ void OPCUA_MGR::setMGMCommand(EMGMCommandType paCMD, CStringDictionary::TStringI
}
}
if (paAdditionalParams != nullptr) {
mCommand.mAdditionalParams.fromString(paAdditionalParams);
mCommand.mAdditionalParams = CIEC_STRING(paAdditionalParams);
}
}

Expand All @@ -1049,12 +1157,13 @@ std::string OPCUA_MGR::getInputValue(UA_String paInput) {
return inputNameStr.substr(0, paInput.length);
}

void OPCUA_MGR::parseDestinationName(std::string& paDestination, std::vector<std::string>& paFbName) {
size_t index = paDestination.find_first_of(".");
void OPCUA_MGR::parseDestinationName(const std::string& paDestination, std::vector<std::string>& paFbName) {
std::string dst(paDestination);
size_t index = dst.find_first_of(".");
while (index != std::string::npos) {
paFbName.push_back(paDestination.substr(0, index));
paDestination = paDestination.substr(paFbName.back().length() + 1);
index = paDestination.find_first_of(".");
paFbName.push_back(dst.substr(0, index));
dst = dst.substr(paFbName.back().length() + 1);
index = dst.find_first_of(".");
}
paFbName.push_back(paDestination.substr(0, index));
paFbName.push_back(dst.substr(0, index));
}
Loading