Skip to content

Commit

Permalink
Add support for sending data with nested Structs
Browse files Browse the repository at this point in the history
  • Loading branch information
m-meingast authored and azoitl committed Jan 20, 2025
1 parent 25d5fb0 commit 82dfb88
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 2 deletions.
47 changes: 47 additions & 0 deletions src/com/opc_ua/opcua_local_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "forte_printer.h"
#include "../../arch/utils/mainparam_utils.h"
#include "opcua_local_handler.h"
#include "struct_action_info.h"
#ifdef FORTE_COM_OPC_UA_MULTICAST
#include "detail/lds_me_handler.h"
#endif //FORTE_COM_OPC_UA_MULTICAST
Expand Down Expand Up @@ -361,6 +362,24 @@ UA_StatusCode COPC_UA_Local_Handler::executeAction(CActionInfo &paActionInfo) {
return retVal;
}

UA_StatusCode COPC_UA_Local_Handler::executeStructAction(CActionInfo &paActionInfo, CIEC_ANY &paMember) {
UA_StatusCode retVal = UA_STATUSCODE_BADINTERNALERROR;

CCriticalRegion criticalRegion(mServerAccessMutex);
switch(paActionInfo.getAction()){
case CActionInfo::eWrite:
retVal = executeStructWrite(paActionInfo, paMember);
break;
default: //eCallMethod, eSubscribe will never reach here since they weren't initialized. eRead is a Subscribe FB
DEVLOG_ERROR("[OPC UA LOCAL]: Struct Action %d to be executed is unknown or invalid\n", paActionInfo.getAction());
break;
}

mServerNeedsIteration.inc();

return retVal;
}

UA_StatusCode COPC_UA_Local_Handler::uninitializeAction(CActionInfo &paActionInfo) {
UA_StatusCode retVal = UA_STATUSCODE_BADINTERNALERROR;
CCriticalRegion criticalRegion(mServerAccessMutex);
Expand Down Expand Up @@ -871,6 +890,34 @@ UA_StatusCode COPC_UA_Local_Handler::executeWrite(CActionInfo &paActionInfo) {
return retVal;
}

UA_StatusCode COPC_UA_Local_Handler::executeStructWrite(CActionInfo &paActionInfo, CIEC_ANY &paMember) {
UA_StatusCode retVal = UA_STATUSCODE_GOOD;

if(paMember.getDataTypeID() == CIEC_ANY::e_STRUCT) {
CIEC_STRUCT& structType = static_cast<CIEC_STRUCT&>(paMember);
CStructActionInfo &structActionInfo = static_cast<CStructActionInfo&>(paActionInfo);
std::vector<std::shared_ptr<CActionInfo>> memberActionInfos = structActionInfo.getMemberActionInfos();
for(size_t i = 0; i < memberActionInfos.size(); i++) {
std::shared_ptr<CActionInfo> memberActionInfo = memberActionInfos[i];
CIEC_ANY *member = structType.getMember(i);
retVal = executeStructWrite(*memberActionInfo, *member);
if(retVal != UA_STATUSCODE_GOOD) {
return retVal;
}
}
} else {
auto it = paActionInfo.getNodePairInfo().begin();
retVal = updateNodeValue(*it->getNodeId(), &paMember);
if(UA_STATUSCODE_GOOD != retVal) {
DEVLOG_ERROR("[OPC UA LOCAL]: Could not convert value to write for node %s at FB %s. Error: %s\n",
(*paActionInfo.getNodePairInfo().begin()).getBrowsePath(),
paActionInfo.getLayer().getCommFB()->getInstanceName(), UA_StatusCode_name(retVal));
return retVal;
}
}
return retVal;
}

UA_StatusCode COPC_UA_Local_Handler::executeCreateMethod(CActionInfo &paActionInfo) {
//This is the return of a local method call, when RSP is triggered

Expand Down
16 changes: 16 additions & 0 deletions src/com/opc_ua/opcua_local_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ class COPC_UA_Local_Handler : public COPC_UA_HandlerAbstract, public CThread {
*/
UA_StatusCode initializeActionForObjectStruct(std::shared_ptr<CActionInfo> &paActionInfo, CIEC_ANY &paMember);

/**
* Execute action for the given struct member
* @param paActionInfo Action of Struct member to be executed
* @param paMember Struct member
* @return UA_STATUSCODE_GOOD if no problem occurred, other value otherwise
*/
UA_StatusCode executeStructAction(CActionInfo &paActionInfo, CIEC_ANY &paMember);

/**
* Splits a browsepath into folders and node name. The non-existing folders are created in the local server
* @param paBrowsePath Browsepath to be splitted
Expand Down Expand Up @@ -524,6 +532,14 @@ class COPC_UA_Local_Handler : public COPC_UA_HandlerAbstract, public CThread {
*/
UA_StatusCode executeWrite(CActionInfo &paActionInfo);

/**
* Execute the write action for a struct member
* @param paActionInfo Action to be executed
* @param paMember Struct member
* @return UA_STATUSCODE_GOOD is no problem occurred, other value otherwise
*/
UA_StatusCode executeStructWrite(CActionInfo &paActionInfo, CIEC_ANY &paMember);

/**
* When the FB of the local method is triggered to signalize the end of the method, this function is called
* @param paActionInfo Action to be executed
Expand Down
13 changes: 11 additions & 2 deletions src/com/opc_ua/opcua_objectstruct_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,17 @@ CIEC_ANY const *COPC_UA_ObjectStruct_Helper::getStructMember(CActionInfo &paActi
}

forte::com_infra::EComResponse COPC_UA_ObjectStruct_Helper::executeStructAction() {
for(std::shared_ptr<CActionInfo> actionInfo : mStructMemberActionInfos) {
if(UA_STATUSCODE_GOOD != mHandler->executeAction(*actionInfo)) {
COPC_UA_Local_Handler* localHandler = static_cast<COPC_UA_Local_Handler*>(mHandler);
if(!localHandler) {
DEVLOG_ERROR("[OPC UA OBJECT STRUCT HELPER]: Failed to get LocalHandler because LocalHandler is null!\n");
return e_InitTerminated;
}
CIEC_ANY** apoDataPorts = mLayer.getCommFB()->getSDs();
CIEC_STRUCT& structType = static_cast<CIEC_STRUCT&>(apoDataPorts[0]->unwrap());
for(size_t i = 0; i < mStructMemberActionInfos.size(); i++) {
std::shared_ptr<CActionInfo> actionInfo = mStructMemberActionInfos[i];
CIEC_ANY *member = structType.getMember(i);
if(localHandler->executeStructAction(*actionInfo, *member) != UA_STATUSCODE_GOOD) {
return e_ProcessDataSendFailed;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/com/opc_ua/struct_action_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class CStructActionInfo : public CStructMemberActionInfo {
mStructMemberActionInfos.insert(mStructMemberActionInfos.end(), paActionInfos.begin(), paActionInfos.end());
}

std::vector<std::shared_ptr<CActionInfo>> &getMemberActionInfos() {
return mStructMemberActionInfos;
}

private:

std::vector<std::shared_ptr<CActionInfo>> mStructMemberActionInfos;
Expand Down

0 comments on commit 82dfb88

Please sign in to comment.