File: C:/Redmine-4.x/redmine-4.2.9/files/170927151459_PieceOfCode-27-09.cpp
///-------------------------------------------------------------------------------------------------
/// <summary> Decode node identifier list. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 23/07/2017. </remarks>
///
/// <param name="byteStringToDecode"> The byte string to decode. </param>
/// <param name=">"> [in,out] If non-null, the > </param>
///
/// <returns> A Vpi_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
Vpi_StatusCode UASubSystem::CVpiUaClnt::DecodeNodeIdList(Vpi_ByteString byteStringToDecode, vector<OpcUa_NodeId*>* pNodeIdList)
{
Vpi_StatusCode uStatus = Vpi_Good;
union
{
OpcUa_Byte chData[2];
OpcUa_UInt16 uiVal;
} eTmp2Bytes;
//union
//{
// OpcUa_Byte chData[4];
// OpcUa_UInt32 uiVal;
//} eTmp4Bytes;
//OpcUa_NodeId nodeId;
OpcUa_UInt16 uiNodeOfNodeId = 0;
// First extract the number of NodeId in the byteString
memcpy(eTmp2Bytes.chData,&byteStringToDecode.Data[0], 2);
uiNodeOfNodeId = eTmp2Bytes.uiVal;
if (uiNodeOfNodeId > 0)
{
Vpi_UInt32 index = 2;
for (Vpi_UInt16 i = 0; i < uiNodeOfNodeId; i++)
{
Vpi_Byte NodeIdLen=byteStringToDecode.Data[index];
if (NodeIdLen > 0)
{
Vpi_CharA* pszNodeId = (Vpi_CharA*)malloc(NodeIdLen + 1);
ZeroMemory(pszNodeId, NodeIdLen + 1);
memcpy(pszNodeId, &byteStringToDecode.Data[index+1], NodeIdLen);
OpcUa_NodeId* pNodeId = (OpcUa_NodeId*)OpcUa_Alloc(sizeof(OpcUa_NodeId));
OpcUa_NodeId_Initialize(pNodeId);
OpcUa_String szNodeId;
OpcUa_String_Initialize(&szNodeId);
OpcUa_String_AttachCopy(&szNodeId, pszNodeId);
OpenOpcUa_StringToNodeId(szNodeId, pNodeId);
pNodeIdList->push_back(pNodeId);
OpcUa_String_Clear(&szNodeId);
index += (NodeIdLen+1);
}
else
break;
}
}
else
uStatus = Vpi_BadNothingToDo;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Is subscription detail changed. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 21/09/2017. </remarks>
///
/// <returns> A Vpi_Boolean. </returns>
///-------------------------------------------------------------------------------------------------
Vpi_Boolean UASubSystem::CVpiUaClnt::IsSubscriptionDetailChanged(void)
{
Vpi_Boolean bChanged = Vpi_False;
Vpi_StatusCode uStatus = Vpi_Good;
// Read the NodeId called SubscriptionDetail in the server to retrieve the list of nodeId to subscribe to in the wrapped server
// The SubscriptionDetail nodeId is a numerical nodeId. It is by design at SubSystemId + 6
CVpiInternalData* pVpiInternalData = GetVpiInternalData();
Vpi_NodeId subscribedTagDetailNodeId = pVpiInternalData->GetSubsystemId();
subscribedTagDetailNodeId.Identifier.Numeric += 6;
subscribedTagDetailNodeId.NamespaceIndex = 1; // Must be 1. Adjust it. Just in case of a wrong configuration
Vpi_DataValue dataValue;
Vpi_DataValue_Initialize(&dataValue);
uStatus = pVpiInternalData->ProcessReadtransaction(subscribedTagDetailNodeId, &dataValue);
if (uStatus == Vpi_Good)
{
if (dataValue.Value.Value.ByteString.Length > 0)
{
if (m_ByteStringSubscriptionDetail.Data)
{
if (memcmp(dataValue.Value.Value.ByteString.Data, m_ByteStringSubscriptionDetail.Data, dataValue.Value.Value.ByteString.Length) != 0)
{
// Save the m_ByteStringSubscriptionDetail
Vpi_ByteString_Clear(&(m_ByteStringSubscriptionDetail));
Vpi_ByteString_Initialize(&(m_ByteStringSubscriptionDetail));
Vpi_ByteString_CopyTo(&dataValue.Value.Value.ByteString, &(m_ByteStringSubscriptionDetail));
bChanged = Vpi_True;
}
}
else
{
// Save the m_ByteStringSubscriptionDetail
Vpi_ByteString_Clear(&(m_ByteStringSubscriptionDetail));
Vpi_ByteString_Initialize(&(m_ByteStringSubscriptionDetail));
Vpi_ByteString_CopyTo(&dataValue.Value.Value.ByteString, &(m_ByteStringSubscriptionDetail));
bChanged = Vpi_True;
}
}
}
else
Vpi_Trace(pVpiInternalData->m_ProxyStubConfiguration, VPI_TRACE_EXTRA_INFO, "UAClntThread>ProcessReadtransaction failed uStatus=0x%05x\n", uStatus);
return bChanged;
}