UInt32 converted to Double

Questions regarding the use of the C++ SDK for Server or Client development or integration into customer products ...

Moderator: uasdkcpp

Post Reply
dave
Jr. Member
Jr. Member
Posts: 3
Joined: 30 Jun 2015, 12:53

UInt32 converted to Double

Post by dave »

Hi,

I'm having some trouble with a property of DataType UInt32 being transformed to Double unexpectedly. We are using the C++ SDK version 1.4.3.

The DataType of the property ExpectedNumberOfBirds is defined in my model as UInt32. In the generated code I also see that the type of this property is a UInt32; the getter and setter functions show this.

When browsing through the address space using UaExpert, the window on the right shows DataType UInt32 for the ExpectedNumberOfBirds node. However, when I drag this node to the Data Access View, the DataType is Double:
ua_expert.png
Using another client (not UaExpert) I confirmed that the actual returned DataType is indeed Double, while it should be UInt32. Finally, I used Wireshark to examine the ReadResponse message from the server. This message actually contains the DataType Double.

Wireshark ReadRequest:
ws_readrequest.png
Wireshark ReadResponse:
ws_readresponse.png
The trace logging shows the ReadRequest and ReadResponse message produced by reading the ExpectedNumberOfBirds Node. The stack indicates the ReadReponse contains value 7 (=UInt32 builtin type) for attribute 14 (=DataType):

Code: Select all

11:36:40.934Z|4|F20CC700* [uastack]  * OpcUa_TcpListener_EventCallback: Socket(0xe9bae0), Port(0), Data(0xe958d0), Event(OPCUA_SOCKET_READ_EVENT)
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_TcpListener_ReadEventHandler: Connection 0xe97250.
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_TcpStream_DataReady: Read 8 bytes.
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_TcpStream_DataReady: Read 718 bytes.
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_TcpStream_DataReady: total 726 bytes (718 last) of 718 (w/o header) received.
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_TcpListener_ReadEventHandler: MessageType SecureChannel Message
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_TcpListener_ProcessRequest: Handing TcpInputStream 0x7f09e00138d0 to upper layer!
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_SecureListener_OnNotify: Request
11:36:40.934Z|4|F20CC700* [uastack] SecureStream - CheckInputHeaderType - Common Service
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_SecureListener_ProcessSessionCallRequest: SecureChannelId 1569736928, SecurityTokenId 1
11:36:40.934Z|4|F20CC700* [uastack] GetSecurityKeyset: Keysets for token id 1 at channel 1569736928 requested.
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_SecureListener_ProcessSessionCallRequest: All 1 chunks received; start processing!
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_SecureStream_AppendInput: Appending buffer at index 0 with data 0x0x7f09e00142e0!
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_SecureStream_AppendInput: appended chunk with SN 129, RID 79
11:36:40.934Z|4|F20CC700* [uastack] ReleaseSecurityKeyset: Keyset for token 1 released.
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_Endpoint_OnNotify: Underlying listener raised request event!
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_SecureStream_Read: end of buffer reached: 1 requested, 0 available in buffer; need to skip)!
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_Endpoint_BeginProcessRequest: Service with RequestTypeId 629 called! (Request: ReadRequest)
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_Endpoint_BeginProcessRequest: Invoking service handler with context 0x0x7f09e000d530!
11:36:40.934Z|4|F20CC700* ==> UaServer::Read [Request=1000144]
11:36:40.934Z|6|F20CC700* --> UaSession::startingServiceProcessing [ID=1569736911]
11:36:40.934Z|6|F20CC700* <-- UaSession::startingServiceProcessing - activeServiceCount = 3
11:36:40.934Z|6|F20CC700* --> UaTransactionManager::beginRead with 8 nodes
11:36:40.934Z|7|F20CC700* Read Request [Request=1000144]:
11:36:40.934Z|7|F20CC700*   MaxAge             = 0.000000 ms
11:36:40.934Z|7|F20CC700*   TimestampsToReturn = Neither
11:36:40.934Z|7|F20CC700*   NoOfNodesToRead = 8
11:36:40.934Z|7|F20CC700*     Node[0] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=2
11:36:40.934Z|7|F20CC700*     Node[1] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=3
11:36:40.934Z|7|F20CC700*     Node[2] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=4
11:36:40.934Z|7|F20CC700*     Node[3] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=5
11:36:40.934Z|7|F20CC700*     Node[4] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=14  <--- request DataType
11:36:40.934Z|7|F20CC700*     Node[5] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=15
11:36:40.934Z|7|F20CC700*     Node[6] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=16
11:36:40.934Z|7|F20CC700*     Node[7] NS2|String|{8b2b83ac-f56d-4805-82c6-01859780d476}.ExpectedNumberOfBirds Attribute=10
11:36:40.934Z|6|F20CC700* --> IOManagerUaNode::beginTransaction ID=1
11:36:40.934Z|6|F20CC700* <-- IOManagerUaNode::beginTransaction [ret=0x0]
11:36:40.934Z|6|F20CC700* --> IOManagerUaNode::finishTransaction ID=1
11:36:40.934Z|6|F20CC700* <-- IOManagerUaNode::finishTransaction [ret=0x0]
11:36:40.934Z|6|F20CC700* <-- UaTransactionManager::beginRead [ret=0x0]
11:36:40.934Z|4|F20CC700* <== UaServer::Read
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_Endpoint_BeginSendResponse: Context 0x0x7f09e000d530
11:36:40.934Z|7|F21CD700* Read Response [Request=1000144]:
11:36:40.934Z|7|F21CD700*   NoOfResults = 8
11:36:40.934Z|4|F20CC700* [uastack] OpcUa_Endpoint_BeginProcessRequest: Service handler returned! (0x00000000)
11:36:40.934Z|4|F20CC700* [uastack]  * OpcUa_TcpListener_EventCallback: Event Handler returned with status 0x00000000.
11:36:40.934Z|7|F21CD700*     Node[0] SrvTS=00:00:00.000Z SrcTS=00:00:00.000Z Val=2
11:36:40.934Z|7|F21CD700*     Node[1] SrvTS=00:00:00.000Z SrcTS=00:00:00.000Z Val=ExpectedNumberOfBirds
11:36:40.934Z|7|F21CD700*     Node[2] SrvTS=00:00:00.000Z SrcTS=00:00:00.000Z Val=ExpectedNumberOfBirds
11:36:40.934Z|7|F21CD700*     Node[3] Status = 0x80350000
11:36:40.934Z|7|F21CD700*     Node[4] SrvTS=00:00:00.000Z SrcTS=00:00:00.000Z Val=7     <----- value 7 is NodeId from UInt32 builtin type
11:36:40.934Z|7|F21CD700*     Node[5] SrvTS=00:00:00.000Z SrcTS=00:00:00.000Z Val=-1
11:36:40.934Z|7|F21CD700*     Node[6] SrvTS=00:00:00.000Z SrcTS=00:00:00.000Z Val={}
11:36:40.934Z|7|F21CD700*     Node[7] Status = 0x80350000
11:36:40.934Z|6|F21CD700* --> UaSession::lockSendResponse [ID=1569736911]
11:36:40.934Z|6|F21CD700* <-- UaSession::lockSendResponse
11:36:40.934Z|4|F21CD700* CALL  Send Response for Read [Request=1000144][ServiceResult=0x0]
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_Endpoint_EndSendResponse: Status 0x00000000, Context 0x0x7f09e000d530!
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_SecureListener_BeginSendResponse: 1 streams now active at channel 1569736928
11:36:40.934Z|4|F21CD700* [uastack] GetCurrentSecuritySet: Current Keysets requested. Returned token id is 1
11:36:40.934Z|4|F21CD700* [uastack] ReleaseSecurityKeyset: Keyset for token 1 released.
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_SecureListener_EndSendResponse: ID 79, Status 0x00000000
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_SecureListener_EndSendResponse: 0 stream remaining at channel 1569736928!
11:36:40.934Z|4|F21CD700* [uastack] GetCurrentSecuritySet: Current Keysets requested. Returned token id is 1
11:36:40.934Z|4|F21CD700* [uastack] GetCurrentSecuritySet: Current Keysets requested. Returned token id is 1
11:36:40.934Z|4|F21CD700* [uastack] ReleaseSecurityKeyset: Keyset for token 1 released.
11:36:40.934Z|4|F21CD700* [uastack] ReleaseSecurityKeyset: Keyset for token 1 released.
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_TcpStream_Flush: Flush no. 1 with 5000 max flushes and final flag 1!
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_TcpStream_Flush: Messagelength is 153! Last Call!
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_TcpStream_Flush: Buffer emptied!
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_SecureStream_Flush: Flush number 0! (Last)
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_TcpListener_EndSendResponse: Status 0x00000000, Stream 0x7f09d8000b60, Connection 0xe97250
11:36:40.934Z|4|F21CD700* [uastack] SecureListener - ChannelManager_ReleaseChannel: invalid ref count!
11:36:40.934Z|4|F21CD700* [uastack] OpcUa_Endpoint_DeleteContext!
11:36:40.934Z|4|F21CD700* CLEAN Send Response for Read
11:36:40.934Z|6|F21CD700* --> UaSession::unlockSendResponse [ID=1569736911]
11:36:40.934Z|6|F21CD700* <-- UaSession::unlockSendResponse
11:36:40.934Z|6|F21CD700* --> UaSession::finishedServiceProcessing [ID=1569736911]
11:36:40.934Z|6|F21CD700* <-- UaSession::finishedServiceProcessing - activeServiceCount = 2
11:36:40.934Z|4|F21CD700* DONE  Send Response for Read
Conclusion: while the logging shows that the ReadResponse contains DataType UInt32, the clients (and Wireshark) show that actually DataType Double is sent. This is unexpected and doesn't comply with the model. Similar behavior is seen for Nodes with DataType ByteString, which is received by clients as DataType String.

Do you have any ideas on what might be going wrong?

Regards,
Dave

dave
Jr. Member
Jr. Member
Posts: 3
Joined: 30 Jun 2015, 12:53

Re: UInt32 converted to Double

Post by dave »

It seems there is a problem in uavariant.h regarding the assignment operator overloaded functions:

Code: Select all

    UaVariant& operator=(const OpcUa_Variant&);
    UaVariant& operator=(const UaVariant&);
    UaVariant& operator=(double);
    UaVariant& operator=(const UaString&);
The class doesn't contain overloaded functions for all types allowed by variants. For some reason, when calling the assignment operator function with a UInt32 type, the overloaded method for type double is executed. This causes the unwanted conversion from UInt32 to double.

Consider the following pseudo code example where the UaVariant is expected to contain a UInt32 type, while instead it will contain a Double.

Code: Select all

UaVariant myUint;
myUint = UInt32(10); // now the variant will contain a Double
Current workaround is using the set functions from UaVariant. However, this issue should probably be addressed in the SDK.

User avatar
Support Team
Hero Member
Hero Member
Posts: 3072
Joined: 18 Mar 2011, 15:09

Re: UInt32 converted to Double

Post by Support Team »

Hi Dave,

You should always use the UaVariant::setXxx methods. Even if we add more assignment operators, we cannot cover all possible built-in types since some logically different built-in types share a programming language data types (e.g. UInt32/StatusCode and Boolean/Byte).

We will check what we can add as assignment operators in the next SDK version.

What we do not understand is why this happens with the generated getter/setter functions. The generated code for a UInt32 variable setter is using the UaVariant::setUInt32() to assign the value to a UaVariant.

The generated code should look like

Code: Select all

void YourClass::setExpectedNumberOfBirds(OpcUa_UInt32 ExpectedNumberOfBirds)
{
    UaVariant value;
    value.setUInt32(ExpectedNumberOfBirds);
    UaDataValue dataValue;
    dataValue.setValue(value, OpcUa_True, OpcUa_True);
    m_pSize->setValue(NULL, dataValue, OpcUa_False);
}

Best Regards,
Unified Automation Support Team

dave
Jr. Member
Jr. Member
Posts: 3
Joined: 30 Jun 2015, 12:53

Re: UInt32 converted to Double

Post by dave »

Thanks for your reply. Using only the generated code does indeed give no problems. We however made some wrappers that didn't use the Set functions on the UAVariant. Now we know that we should use those functions.

Post Reply