summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Keller <Rainer.Keller@qt.io>2018-10-08 10:55:33 +0200
committerRainer Keller <Rainer.Keller@qt.io>2018-10-11 08:03:56 +0000
commit9a9ac65defef1b42888ad19ba0aa38f1fe2b239e (patch)
treea27c00d879641c5ed50e329850baaa6b6d44e1b2
parent33b653e4d6882431e909dcb6c4f76309a3719fc9 (diff)
uacpp: Fix time converterv5.12.0-beta3v5.12.0-beta2
Change-Id: I9cc924f6ca834bebb4afd29255c5c63a7c6130eb Reviewed-by: Jannis Völker <jannis.voelker@basyskom.com> Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
-rw-r--r--src/plugins/opcua/uacpp/quacppvalueconverter.cpp7
-rw-r--r--tests/auto/qopcuaclient/tst_client.cpp17
-rw-r--r--tests/open62541-testserver/main.cpp1
-rw-r--r--tests/open62541-testserver/testserver.cpp33
-rw-r--r--tests/open62541-testserver/testserver.h1
5 files changed, 57 insertions, 2 deletions
diff --git a/src/plugins/opcua/uacpp/quacppvalueconverter.cpp b/src/plugins/opcua/uacpp/quacppvalueconverter.cpp
index 58d0eb1..5aa4f5c 100644
--- a/src/plugins/opcua/uacpp/quacppvalueconverter.cpp
+++ b/src/plugins/opcua/uacpp/quacppvalueconverter.cpp
@@ -478,7 +478,8 @@ void scalarFromQVariant<OpcUa_DateTime, QDateTime>(const QVariant &var, OpcUa_Da
{
// OPC-UA part 3, Table C.9
const QDateTime uaEpochStart(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
- const UaDateTime dt = UaDateTime(var.toDateTime().toMSecsSinceEpoch() - uaEpochStart.toMSecsSinceEpoch());
+ // OpcUa time is defined in part 6, 5.2.2.5 in 100ns which need to be converted to milliseconds.
+ const UaDateTime dt = UaDateTime((var.toDateTime().toMSecsSinceEpoch() - uaEpochStart.toMSecsSinceEpoch()) * 10000);
*ptr = dt;
}
@@ -952,7 +953,9 @@ QDateTime toQDateTime(const OpcUa_DateTime *dt)
// OPC-UA part 3, Table C.9
const QDateTime uaEpochStart(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
const UaDateTime temp(*dt);
- return uaEpochStart.addMSecs(temp).toLocalTime();
+
+ // OpcUa time is defined in part 6, 5.2.2.5 in 100ns which need to be converted to milliseconds.
+ return uaEpochStart.addMSecs(((quint64)temp) / 10000).toLocalTime();
}
}
diff --git a/tests/auto/qopcuaclient/tst_client.cpp b/tests/auto/qopcuaclient/tst_client.cpp
index 06ce0a9..f12a96a 100644
--- a/tests/auto/qopcuaclient/tst_client.cpp
+++ b/tests/auto/qopcuaclient/tst_client.cpp
@@ -462,6 +462,9 @@ private slots:
defineDataMethod(addNamespace_data)
void addNamespace();
+ void fixedTimestamp();
+ defineDataMethod(fixedTimestamp_data)
+
defineDataMethod(resolveBrowsePath_data)
void resolveBrowsePath();
@@ -3621,6 +3624,20 @@ void Tst_QOpcUaClient::addNamespace()
QCOMPARE(methodSpy.at(0).at(1).value<quint16>(), updatedNamespaceArray.indexOf(newNamespaceName));
}
+void Tst_QOpcUaClient::fixedTimestamp()
+{
+ QFETCH(QOpcUaClient *, opcuaClient);
+ OpcuaConnector connector(opcuaClient, m_endpoint);
+
+ QScopedPointer<QOpcUaNode> node(opcuaClient->node("ns=2;s=Demo.Static.FixedTimestamp"));
+ QVERIFY(node != nullptr);
+ READ_MANDATORY_VARIABLE_NODE(node);
+ QVariant value = node->attribute(QOpcUa::NodeAttribute::Value);
+ QVERIFY(value.isValid());
+ QCOMPARE(value.type(), QVariant::DateTime);
+ QCOMPARE(value.toDateTime(), QDateTime(QDate(2012, 12, 19), QTime(13, 37)));
+}
+
void Tst_QOpcUaClient::connectionLost()
{
// Restart the test server if necessary
diff --git a/tests/open62541-testserver/main.cpp b/tests/open62541-testserver/main.cpp
index 58df107..bbd51a8 100644
--- a/tests/open62541-testserver/main.cpp
+++ b/tests/open62541-testserver/main.cpp
@@ -189,6 +189,7 @@ int main(int argc, char **argv)
QOpcUa::Types::Argument);
server.addVariable(testFolder, "ns=2;s=Demo.Static.Scalar.ExtensionObject", "ExtensionObjectScalarTest",
QOpcUa::QExtensionObject(), QOpcUa::Types::ExtensionObject);
+ server.addNodeWithFixedTimestamp(testFolder, "ns=2;s=Demo.Static.FixedTimestamp", "FixedTimestamp");
// Create folders containing child nodes with string, guid and opaque node ids
UA_NodeId testStringIdsFolder = server.addFolder("ns=3;s=testStringIdsFolder", "testStringIdsFolder");
diff --git a/tests/open62541-testserver/testserver.cpp b/tests/open62541-testserver/testserver.cpp
index f7dd957..d83694d 100644
--- a/tests/open62541-testserver/testserver.cpp
+++ b/tests/open62541-testserver/testserver.cpp
@@ -552,4 +552,37 @@ UA_StatusCode TestServer::addNamespaceMethod(UA_Server *server, const UA_NodeId
return UA_STATUSCODE_GOOD;
}
+UA_NodeId TestServer::addNodeWithFixedTimestamp(const UA_NodeId &folder, const QString &nodeId, const QString &displayName)
+{
+ UA_NodeId variableNodeId = Open62541Utils::nodeIdFromQString(nodeId);
+
+ UA_VariableAttributes attr = UA_VariableAttributes_default;
+ attr.value = QOpen62541ValueConverter::toOpen62541Variant(QDateTime(QDate(2012, 12, 19), QTime(13, 37)), QOpcUa::DateTime);
+ attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en_US", displayName.toUtf8().constData());
+ attr.dataType = attr.value.type->typeId;
+ attr.accessLevel = UA_ACCESSLEVELMASK_READ; // Read Only
+
+ UA_QualifiedName variableName;
+ variableName.namespaceIndex = variableNodeId.namespaceIndex;
+ variableName.name = attr.displayName.text;
+
+ UA_NodeId resultId;
+ UA_StatusCode result = UA_Server_addVariableNode(m_server,
+ variableNodeId,
+ folder,
+ UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
+ variableName,
+ UA_NODEID_NULL,
+ attr,
+ NULL,
+ &resultId);
+
+ if (result != UA_STATUSCODE_GOOD) {
+ qWarning() << "Could not add variable:" << result;
+ return UA_NODEID_NULL;
+ }
+
+ return resultId;
+}
+
QT_END_NAMESPACE
diff --git a/tests/open62541-testserver/testserver.h b/tests/open62541-testserver/testserver.h
index f8a5ff9..2cebfd9 100644
--- a/tests/open62541-testserver/testserver.h
+++ b/tests/open62541-testserver/testserver.h
@@ -68,6 +68,7 @@ public:
UA_NodeId addMultiplyMethod(const UA_NodeId &folder, const QString &variableNode, const QString &description);
UA_NodeId addMultipleOutputArgumentsMethod(const UA_NodeId &folder, const QString &variableNode, const QString &description);
UA_NodeId addAddNamespaceMethod(const UA_NodeId &folder, const QString &variableNode, const QString &description);
+ UA_NodeId addNodeWithFixedTimestamp(const UA_NodeId &folder, const QString &nodeId, const QString &displayName);
static UA_StatusCode multiplyMethod(UA_Server *server, const UA_NodeId *sessionId, void *sessionHandle,
const UA_NodeId *methodId, void *methodContext,