1// Copyright (C) 2021 basysKom GmbH, opensource@basyskom.com
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qopcuahistoryreadresponseimpl_p.h"
5
6QT_BEGIN_NAMESPACE
7
8quint64 QOpcUaHistoryReadResponseImpl::m_currentHandle = 0;
9
10QOpcUaHistoryReadResponseImpl::QOpcUaHistoryReadResponseImpl(const QOpcUaHistoryReadRawRequest &request)
11 : m_requestType(RequestType::ReadRaw)
12 , m_readRawRequest(request)
13 , m_handle(++m_currentHandle)
14{
15}
16
17QOpcUaHistoryReadResponseImpl::~QOpcUaHistoryReadResponseImpl()
18{
19 releaseContinuationPoints();
20}
21
22bool QOpcUaHistoryReadResponseImpl::hasMoreData() const
23{
24 return m_state == QOpcUaHistoryReadResponse::State::MoreDataAvailable;
25}
26
27bool QOpcUaHistoryReadResponseImpl::readMoreData()
28{
29 if (!hasMoreData())
30 return false;
31
32 if (m_requestType == RequestType::ReadRaw) {
33 QOpcUaHistoryReadRawRequest request;
34 request.setStartTimestamp(m_readRawRequest.startTimestamp());
35 request.setEndTimestamp(m_readRawRequest.endTimestamp());
36 request.setNumValuesPerNode(m_readRawRequest.numValuesPerNode());
37 request.setReturnBounds(m_readRawRequest.returnBounds());
38
39 int arrayIndex = 0;
40 QList<int> newDataMapping;
41 QList<QByteArray> newContinuationPoints;
42
43 for (const auto &continuationPoint : m_continuationPoints) {
44 int mappingIndex = 0;
45 if (m_dataMapping.empty())
46 mappingIndex = arrayIndex;
47 else
48 mappingIndex = m_dataMapping.at(i: arrayIndex);
49
50 if (!continuationPoint.isEmpty()) {
51 newDataMapping.push_back(t: mappingIndex);
52 newContinuationPoints.push_back(t: continuationPoint);
53 request.addNodeToRead(nodeToRead: m_readRawRequest.nodesToRead().at(i: mappingIndex));
54 }
55
56 ++arrayIndex;
57 }
58
59 m_dataMapping = newDataMapping;
60
61 m_continuationPoints = newContinuationPoints;
62 emit historyReadRawRequested(request, continuationPoints: m_continuationPoints, releaseContinuationPoints: false, handle: handle());
63 return true;
64 }
65
66 return false;
67}
68
69QOpcUaHistoryReadResponse::State QOpcUaHistoryReadResponseImpl::state() const
70{
71 return m_state;
72}
73
74bool QOpcUaHistoryReadResponseImpl::releaseContinuationPoints()
75{
76 if (m_requestType == RequestType::ReadRaw) {
77 emit historyReadRawRequested(request: m_readRawRequest, continuationPoints: m_continuationPoints, releaseContinuationPoints: true, handle: handle());
78 setState(QOpcUaHistoryReadResponse::State::Finished);
79 };
80
81 return true;
82}
83
84QList<QOpcUaHistoryData> QOpcUaHistoryReadResponseImpl::data() const
85{
86 return m_data;
87}
88
89QOpcUa::UaStatusCode QOpcUaHistoryReadResponseImpl::serviceResult() const
90{
91 return m_serviceResult;
92}
93
94void QOpcUaHistoryReadResponseImpl::handleDataAvailable(const QList<QOpcUaHistoryData> &data, const QList<QByteArray> &continuationPoints,
95 QOpcUa::UaStatusCode serviceResult, quint64 responseHandle)
96{
97 if (responseHandle != handle())
98 return;
99
100 m_serviceResult = serviceResult;
101 m_continuationPoints = continuationPoints;
102
103 if (m_data.empty()) {
104 m_data = data;
105 } else {
106 int index = 0;
107 for (const auto &result : data) {
108 auto &target = m_data[m_dataMapping.at(i: index++)];
109 target.setStatusCode(result.statusCode());
110 for (const auto &value : result.result()) {
111 target.addValue(value);
112 }
113 }
114 }
115
116 bool found = false;
117 for (const auto &continuationPoint : m_continuationPoints) {
118 if (!continuationPoint.isEmpty()) {
119 setState(QOpcUaHistoryReadResponse::State::MoreDataAvailable);
120 found = true;
121 break;
122 }
123 }
124
125 if (!found)
126 setState(QOpcUaHistoryReadResponse::State::Finished);
127
128 emit readHistoryDataFinished(results: m_data, serviceResult: m_serviceResult);
129}
130
131void QOpcUaHistoryReadResponseImpl::handleRequestError(quint64 requestHandle)
132{
133 if (requestHandle == handle())
134 setState(QOpcUaHistoryReadResponse::State::Error);
135}
136
137quint64 QOpcUaHistoryReadResponseImpl::handle() const
138{
139 return m_handle;
140}
141
142void QOpcUaHistoryReadResponseImpl::setState(QOpcUaHistoryReadResponse::State state)
143{
144 if (m_state != state) {
145 m_state = state;
146 emit stateChanged(state);
147 }
148}
149
150QT_END_NAMESPACE
151

source code of qtopcua/src/opcua/client/qopcuahistoryreadresponseimpl.cpp