[fix]opc_ua_server_s异常处理不当导致fes奔溃修复

This commit is contained in:
liang-ys 2026-04-14 18:08:57 +08:00
parent cc859d1d18
commit 3cfbb53c90
3 changed files with 130 additions and 89 deletions

View File

@ -13,14 +13,14 @@ COpcUaDataProcThread::COpcUaDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr p
m_pChgDiData=NULL;
m_pChgAccData=NULL;
m_pChgMiData=NULL;
m_ptrUaServer=NULL;
m_ptrCFesChan = ptrCFesChan;
m_ptrCFesBase = ptrCFesBase;
m_ptrCurrentChan = ptrCFesChan;
m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan);
m_currentRtuNamespaceIndex=0;
//2020-02-24 thxiao 创建时设置ThreadRun标识。
if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL))
@ -51,7 +51,11 @@ COpcUaDataProcThread::COpcUaDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr p
if(found)
{
initServer();
if(iotSuccess==initServer())
{
initNodeId();
};
}
else
{
@ -70,6 +74,7 @@ COpcUaDataProcThread::~COpcUaDataProcThread()
if(m_ptrUaServer)
{
UA_Server_run_shutdown(m_ptrUaServer);
UA_Server_delete(m_ptrUaServer);
m_ptrUaServer=NULL;
}
@ -86,19 +91,14 @@ int COpcUaDataProcThread::beforeExecute()
void COpcUaDataProcThread::execute()
{
if(m_bReady)
if(!m_bReady)
{
LOGTRACE("COpcUaDataProcThread ChanNo=%d not ready ,check log which has record err", m_ptrCurrentChan->m_Param.ChanNo);
return;
}
if(!m_bServerOK)
{
if(iotSuccess!=initServer())
{
m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown);
LOGERROR("COpcUaDataProcThread ChanNo=%d initServer failed ", m_ptrCurrentChan->m_Param.ChanNo);
return;
}
return;
}
UA_Server_run_iterate(m_ptrUaServer, true);
@ -213,7 +213,7 @@ void COpcUaDataProcThread::handleAiData()
pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint;
UA_NodeId curNodeId=m_vecAiNodeId[aiPoint];
UA_Variant curValue;
fvalue = pFwAi->Value*pFwAi->Coeff + pFwAi->Base;
fvalue = pFwAi->Value; /**pFwAi->Coeff + pFwAi->Base; 2025.3.18已在UpdateFesAiValue 做处理*/
buildValue(pFwAi->ResParam1,fvalue,curValue);
UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue);
if(!UA_StatusCode_isGood(writeStatus))
@ -240,7 +240,7 @@ void COpcUaDataProcThread::handleAccData()
pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint;
UA_NodeId curNodeId=m_vecAccNodeId[accPoint];
UA_Variant curValue;
fvalue = pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base;
fvalue = pFwAcc->Value; /**pFwAcc->Coeff + pFwAcc->Base; 2025.3.18已在UpdateFesAccValue 做处理*/
buildValue(pFwAcc->ResParam1,fvalue,curValue);
UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue);
if(!UA_StatusCode_isGood(writeStatus))
@ -268,7 +268,7 @@ void COpcUaDataProcThread::handleMiData()
UA_NodeId curNodeId=m_vecMiNodeId[miPoint];
UA_Variant curValue;
fvalue = pFwMi->Value*pFwMi->Coeff + pFwMi->Base;
fvalue = pFwMi->Value; /**pFwMi->Coeff + pFwMi->Base;2025.3.18已在UpdateFesMiValue 做处理*/
buildValue(pFwMi->ResParam1,fvalue,curValue);
UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue);
if(!UA_StatusCode_isGood(writeStatus))
@ -321,7 +321,7 @@ void COpcUaDataProcThread::handleChgAiData()
pFwAi = m_ptrCFesRtu->m_pFwAi + pChgAi->RemoteNo;
float AiFloatValue = static_cast<float>(pChgAi->Value * pFwAi->Coeff + pFwAi->Base);
int64 curNodeIdIndex=m_mapAiVecIndex[pChgAi->RemoteNo];
UA_NodeId curNodeId=m_vecMiNodeId[curNodeIdIndex];
UA_NodeId curNodeId=m_vecAiNodeId[curNodeIdIndex];
UA_Variant curValue;
buildValue(pFwAi->ResParam1,AiFloatValue,curValue);
UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue);
@ -363,7 +363,7 @@ void COpcUaDataProcThread::handleChgDiData()
continue;
pFwDi = m_ptrCFesRtu->m_pFwDi+ pChgDi->RemoteNo;
int64 curNodeIdIndex=m_mapAiVecIndex[pChgDi->RemoteNo];
UA_NodeId curNodeId=m_vecMiNodeId[curNodeIdIndex];
UA_NodeId curNodeId=m_vecDiNodeId[curNodeIdIndex];
UA_Variant curValue;
DiValue = pChgDi->Value&0x01;
buildValue(pFwDi->ResParam1,DiValue,curValue);
@ -409,7 +409,7 @@ void COpcUaDataProcThread::handleChgAccData()
pFwAcc = m_ptrCFesRtu->m_pFwAcc + pChgAcc->RemoteNo;
float AccFloatValue = static_cast<float>(pChgAcc->Value * pFwAcc->Coeff + pFwAcc->Base);
int64 curNodeIdIndex=m_mapAiVecIndex[pFwAcc->RemoteNo];
int64 curNodeIdIndex=m_mapAccVecIndex[pFwAcc->RemoteNo];
UA_NodeId curNodeId=m_vecMiNodeId[curNodeIdIndex];
UA_Variant curValue;
buildValue(pFwAcc->ResParam1,AccFloatValue,curValue);
@ -481,10 +481,9 @@ void COpcUaDataProcThread::handleChgMiData()
int COpcUaDataProcThread::initServer()
{
std::string serverIp(m_ptrCFesChan->m_Param.szResParam1);
int port=m_ptrCFesChan->m_Param.LocalPortNo;
m_bServerOK=true;
std::ostringstream oss;
oss << serverIp <<":"<< port;
@ -503,8 +502,10 @@ int COpcUaDataProcThread::initServer()
{
m_ptrUaServer = UA_Server_new();
UA_ServerConfig *config = UA_Server_getConfig(m_ptrUaServer);
UA_String endpointUrl = UA_STRING(const_cast<char*>(resultUrl.c_str()));
config->serverUrls=&endpointUrl;
UA_String *endpointUrl = (UA_String*)UA_malloc(sizeof(UA_String));
*endpointUrl = UA_String_fromChars(resultUrl.c_str());
config->serverUrls=endpointUrl;
UA_StatusCode retval = UA_Server_run_startup(m_ptrUaServer);
if (retval != UA_STATUSCODE_GOOD) {
@ -520,10 +521,19 @@ int COpcUaDataProcThread::initServer()
}
m_bServerOK=true;
m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuNormal);
LOGINFO("COpcUaDataProcThread ChanNo=%d start UAserver %s ok", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str());
return iotSuccess;
if(m_bServerOK)
{
m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuNormal);
LOGINFO("COpcUaDataProcThread ChanNo=%d start UAserver %s ok", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str());
return iotSuccess;
}else
{
m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown);
LOGERROR("COpcUaDataProcThread ChanNo=%d initServer failed ", m_ptrCurrentChan->m_Param.ChanNo);
return iotFailed;
}
}
string COpcUaDataProcThread::getStatusMessage(UA_StatusCode status)
@ -537,47 +547,31 @@ string COpcUaDataProcThread::getStatusMessage(UA_StatusCode status)
int COpcUaDataProcThread::buildNodeId(int nodeIdType, const string &tagStr,UA_NodeId& nodeId)
{
string strNodeId="";
string namespaceIndex="0";
size_t pos = tagStr.find('!');
if(pos != std::string::npos)
{
size_t pos = tagStr.find("]");
if (pos != std::string::npos) {
strNodeId = tagStr.substr(pos + 1);
std::string preStr = tagStr.substr(0, pos);
size_t pos2 = tagStr.find('[');
if(pos2!=std::string::npos)
{
namespaceIndex=preStr.substr(0, pos2);
}
else
{
namespaceIndex=preStr;
}
if(nodeIdType==UA_NODEIDTYPE_NUMERIC)
{
nodeId=UA_NODEID_NUMERIC(atoi(namespaceIndex.c_str()), atoi(strNodeId.c_str()));
}
else if(nodeIdType==UA_NODEIDTYPE_STRING)
{
nodeId=UA_NODEID_STRING_ALLOC(atoi(namespaceIndex.c_str()), strNodeId.c_str());
}else if(nodeIdType==UA_NODEIDTYPE_GUID)
{
nodeId=UA_NODEID_GUID(atoi(namespaceIndex.c_str()), UA_GUID(strNodeId.c_str()));
}else
{
LOGERROR("COpcUaDataProcThread ChanNo=%d get bad tagStr(%s) ,nodeIdType is not imple ", m_ptrCFesChan->m_Param.ChanNo,tagStr.c_str());
return iotFailed;
}
return iotSuccess;
} else {
strNodeId=tagStr;
}
else
if(nodeIdType==UA_NODEIDTYPE_NUMERIC)
{
LOGERROR("COpcUaDataProcThread ChanNo=%d get bad tagStr(%s) ,due to not find (!) ", m_ptrCFesChan->m_Param.ChanNo,tagStr.c_str());
nodeId=UA_NODEID_NUMERIC(m_currentRtuNamespaceIndex, atoi(strNodeId.c_str()));
}
else if(nodeIdType==UA_NODEIDTYPE_STRING)
{
nodeId=UA_NODEID_STRING_ALLOC(m_currentRtuNamespaceIndex, strNodeId.c_str());
}else if(nodeIdType==UA_NODEIDTYPE_GUID)
{
nodeId=UA_NODEID_GUID(m_currentRtuNamespaceIndex, UA_GUID(strNodeId.c_str()));
}else
{
LOGERROR("COpcUaDataProcThread ChanNo=%d get bad tagStr(%s) ,nodeIdType is not imple ", m_ptrCFesChan->m_Param.ChanNo,tagStr.c_str());
return iotFailed;
}
return iotSuccess;
}
int COpcUaDataProcThread::buildValue(int dataType, double curValue, UA_Variant &value)
@ -746,8 +740,25 @@ void COpcUaDataProcThread::clearData()
void COpcUaDataProcThread::initNodeId()
{
char strRtuNo[48];
memset(&strRtuNo[0], 0, sizeof(strRtuNo));
sprintf(strRtuNo, "IOT:RTU%d", m_ptrCFesRtu->m_Param.RtuNo);
UA_UInt16 nsIndex = UA_Server_addNamespace(m_ptrUaServer, strRtuNo);
m_currentRtuNamespaceIndex=nsIndex;
LOGINFO("opc_ua_server_s Namespace(%s)-index(%d) ", strRtuNo,nsIndex);
SFesFwDi *pFwDi=NULL;
for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxDiPoints; diPoint++)
UA_NodeId digitalObjectId; // 保存对象节点的 ID
UA_ObjectAttributes digitalObjectAttr = UA_ObjectAttributes_default;
char DigitalName[] = "Digital";
UA_Server_addObjectNode(m_ptrUaServer, UA_NODEID_NULL,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(1,DigitalName),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
digitalObjectAttr, NULL, &digitalObjectId);
for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++)
{
pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint;
UA_VariableAttributes attr = UA_VariableAttributes_default;
@ -759,18 +770,28 @@ void COpcUaDataProcThread::initNodeId()
UA_NodeId_init(&m_vecDiNodeId[diPoint]);
buildNodeId(pFwDi->ResParam2,pFwDi->szResParam1,m_vecDiNodeId[diPoint]);
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwDi->PointDesc);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(m_ptrUaServer, m_vecDiNodeId[diPoint], parentNodeId,
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(nsIndex, pFwDi->PointDesc);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_HASCOMPONENT);
UA_Server_addVariableNode(m_ptrUaServer, m_vecDiNodeId[diPoint], digitalObjectId,
parentReferenceNodeId, qualifiedName,
UA_NODEID_NULL, attr, NULL, NULL);
m_mapDiVecIndex[pFwDi->RemoteNo]=diPoint;
}
UA_NodeId analogObjectId; // 保存对象节点的 ID
char AnalogName[] = "Analog";
UA_ObjectAttributes analogObjectAttr = UA_ObjectAttributes_default;
UA_Server_addObjectNode(m_ptrUaServer, UA_NODEID_NULL,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(1, AnalogName),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
analogObjectAttr, NULL, &analogObjectId);
SFesFwAi *pFwAi=NULL;
for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxAiPoints; aiPoint++)
for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++)
{
pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint;
UA_VariableAttributes attr = UA_VariableAttributes_default;
@ -782,19 +803,27 @@ void COpcUaDataProcThread::initNodeId()
UA_NodeId_init(&m_vecAiNodeId[aiPoint]);
buildNodeId(pFwAi->ResParam2,pFwAi->szResParam1,m_vecAiNodeId[aiPoint]);
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwAi->PointDesc);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(m_ptrUaServer, m_vecAiNodeId[aiPoint], parentNodeId,
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(nsIndex, pFwAi->PointDesc);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_HASCOMPONENT);
UA_Server_addVariableNode(m_ptrUaServer, m_vecAiNodeId[aiPoint], analogObjectId,
parentReferenceNodeId, qualifiedName,
UA_NODEID_NULL, attr, NULL, NULL);
m_mapAiVecIndex[pFwAi->RemoteNo]=aiPoint;
}
UA_NodeId mixObjectId; // 保存对象节点的 ID
char MixName[] = "Mix";
UA_ObjectAttributes mixObjectAttr = UA_ObjectAttributes_default;
UA_Server_addObjectNode(m_ptrUaServer, UA_NODEID_NULL,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(1, MixName),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
mixObjectAttr, NULL, &mixObjectId);
SFesFwMi *pFwMi=NULL;
for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxMiPoints; miPoint++)
for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxFwMiPoints; miPoint++)
{
pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint;
UA_VariableAttributes attr = UA_VariableAttributes_default;
@ -806,19 +835,28 @@ void COpcUaDataProcThread::initNodeId()
UA_NodeId_init(&m_vecMiNodeId[miPoint]);
buildNodeId(pFwMi->ResParam2,pFwMi->szResParam1,m_vecMiNodeId[miPoint]);
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwMi->PointDesc);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(m_ptrUaServer, m_vecMiNodeId[miPoint], parentNodeId,
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(nsIndex, pFwMi->PointDesc);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_HASCOMPONENT);
UA_Server_addVariableNode(m_ptrUaServer, m_vecMiNodeId[miPoint], mixObjectId,
parentReferenceNodeId, qualifiedName,
UA_NODEID_NULL, attr, NULL, NULL);
m_mapMiVecIndex[pFwMi->RemoteNo]=miPoint;
}
UA_NodeId accObjectId; // 保存对象节点的 ID
UA_ObjectAttributes accObjectAttr = UA_ObjectAttributes_default;
char AccName[] = "Acc";
UA_Server_addObjectNode(m_ptrUaServer, UA_NODEID_NULL,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(1, AccName),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
accObjectAttr, NULL, &accObjectId);
SFesFwAcc *pFwAcc=NULL;
for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxAccPoints; accPoint++)
for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxFwAccPoints; accPoint++)
{
pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint;
UA_VariableAttributes attr = UA_VariableAttributes_default;
@ -830,10 +868,9 @@ void COpcUaDataProcThread::initNodeId()
UA_NodeId_init(&m_vecAccNodeId[accPoint]);
buildNodeId(pFwAcc->ResParam2,pFwAcc->szResParam1,m_vecAccNodeId[accPoint]);
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwAcc->PointDesc);
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES);
UA_Server_addVariableNode(m_ptrUaServer, m_vecAccNodeId[accPoint], parentNodeId,
UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(nsIndex, pFwAcc->PointDesc);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_HASCOMPONENT);
UA_Server_addVariableNode(m_ptrUaServer, m_vecAccNodeId[accPoint], accObjectId,
parentReferenceNodeId, qualifiedName,
UA_NODEID_NULL, attr, NULL, NULL);
@ -847,3 +884,5 @@ void COpcUaDataProcThread::initNodeId()
}

View File

@ -51,7 +51,7 @@ private:
boost::container::map<int64,int64> m_mapAiVecIndex;
boost::container::map<int64,int64> m_mapMiVecIndex;
boost::container::map<int64,int64> m_mapAccVecIndex;
int64 m_currentRtuNamespaceIndex;
private:
void ForwardData();
@ -90,5 +90,7 @@ private:
void initNodeId();
};
typedef boost::shared_ptr<COpcUaDataProcThread> COpcUaDataProcThreadPtr;

View File

@ -209,7 +209,7 @@ int COPCUA::ReadConfigParam()
m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"opc_ua_server_s");
if (m_ProtocolId == -1)
{
LOGDEBUG("ReadConfigParam ProtoclID error");
LOGERROR("ReadConfigParam ProtoclID error");
return iotFailed;
}
LOGINFO("opc_ua_server_s ProtoclID=%d", m_ProtocolId);
@ -219,7 +219,7 @@ int COPCUA::ReadConfigParam()
LOGDEBUG("opc_ua_server_s load opc_ua_server_s.xml error");
return iotSuccess;
}
LOGDEBUG("opc_ua_server_s load opc_ua_server_s.xml ok");
LOGINFO("opc_ua_server_s load opc_ua_server_s.xml ok");
for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++)
{
@ -239,7 +239,7 @@ int COPCUA::ReadConfigParam()
items = 0;
param.pwd = "pwd";
param.pwd = "";
strvalue.clear();
if (config.getStringValue(strRtuNo, "pwd", strvalue) == iotSuccess)
{
@ -247,7 +247,7 @@ int COPCUA::ReadConfigParam()
items++;
}
param.userName = "userName";
param.userName = "";
strvalue.clear();
if (config.getStringValue(strRtuNo, "userName", strvalue) == iotSuccess)
{
@ -257,7 +257,7 @@ int COPCUA::ReadConfigParam()
param.securityPolicy = "securityPolicy";
param.securityPolicy = "";
strvalue.clear();
if (config.getStringValue(strRtuNo, "securityPolicy", strvalue) == iotSuccess)
{
@ -265,7 +265,7 @@ int COPCUA::ReadConfigParam()
items++;
}
param.messageSecurityMode = "messageSecurityMode";
param.messageSecurityMode = "";
strvalue.clear();
if (config.getStringValue(strRtuNo, "messageSecurityMode", strvalue) == iotSuccess)
{
@ -273,7 +273,7 @@ int COPCUA::ReadConfigParam()
items++;
}
param.certificateFilePath = "certificateFilePath";
param.certificateFilePath = "";
strvalue.clear();
if (config.getStringValue(strRtuNo, "certificateFilePath", strvalue) == iotSuccess)
{
@ -282,7 +282,7 @@ int COPCUA::ReadConfigParam()
}
param.privateKeyPath = "privateKeyPath";
param.privateKeyPath = "";
strvalue.clear();
if (config.getStringValue(strRtuNo, "privateKeyPath", strvalue) == iotSuccess)
{