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 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | quint64 QOpcUaHistoryReadResponseImpl::m_currentHandle = 0; |
9 | |
10 | QOpcUaHistoryReadResponseImpl::QOpcUaHistoryReadResponseImpl(const QOpcUaHistoryReadRawRequest &request) |
11 | : m_requestType(RequestType::ReadRaw) |
12 | , m_readRawRequest(request) |
13 | , m_handle(++m_currentHandle) |
14 | { |
15 | } |
16 | |
17 | QOpcUaHistoryReadResponseImpl::~QOpcUaHistoryReadResponseImpl() |
18 | { |
19 | releaseContinuationPoints(); |
20 | } |
21 | |
22 | bool QOpcUaHistoryReadResponseImpl::hasMoreData() const |
23 | { |
24 | return m_state == QOpcUaHistoryReadResponse::State::MoreDataAvailable; |
25 | } |
26 | |
27 | bool 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 | |
69 | QOpcUaHistoryReadResponse::State QOpcUaHistoryReadResponseImpl::state() const |
70 | { |
71 | return m_state; |
72 | } |
73 | |
74 | bool 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 | |
84 | QList<QOpcUaHistoryData> QOpcUaHistoryReadResponseImpl::data() const |
85 | { |
86 | return m_data; |
87 | } |
88 | |
89 | QOpcUa::UaStatusCode QOpcUaHistoryReadResponseImpl::serviceResult() const |
90 | { |
91 | return m_serviceResult; |
92 | } |
93 | |
94 | void 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 | |
131 | void QOpcUaHistoryReadResponseImpl::handleRequestError(quint64 requestHandle) |
132 | { |
133 | if (requestHandle == handle()) |
134 | setState(QOpcUaHistoryReadResponse::State::Error); |
135 | } |
136 | |
137 | quint64 QOpcUaHistoryReadResponseImpl::handle() const |
138 | { |
139 | return m_handle; |
140 | } |
141 | |
142 | void QOpcUaHistoryReadResponseImpl::setState(QOpcUaHistoryReadResponse::State state) |
143 | { |
144 | if (m_state != state) { |
145 | m_state = state; |
146 | emit stateChanged(state); |
147 | } |
148 | } |
149 | |
150 | QT_END_NAMESPACE |
151 | |