/src/opendnp3/cpp/lib/src/master/MasterContext.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2013-2022 Step Function I/O, LLC |
3 | | * |
4 | | * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O |
5 | | * LLC (https://stepfunc.io) under one or more contributor license agreements. |
6 | | * See the NOTICE file distributed with this work for additional information |
7 | | * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license |
8 | | * this file to you under the Apache License, Version 2.0 (the "License"); you |
9 | | * may not use this file except in compliance with the License. You may obtain |
10 | | * a copy of the License at: |
11 | | * |
12 | | * http://www.apache.org/licenses/LICENSE-2.0 |
13 | | * |
14 | | * Unless required by applicable law or agreed to in writing, software |
15 | | * distributed under the License is distributed on an "AS IS" BASIS, |
16 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 | | * See the License for the specific language governing permissions and |
18 | | * limitations under the License. |
19 | | */ |
20 | | #ifndef OPENDNP3_MASTERCONTEXT_H |
21 | | #define OPENDNP3_MASTERCONTEXT_H |
22 | | |
23 | | #include "LayerInterfaces.h" |
24 | | #include "app/AppSeqNum.h" |
25 | | #include "master/HeaderBuilder.h" |
26 | | #include "master/IMasterScheduler.h" |
27 | | #include "master/MasterTasks.h" |
28 | | |
29 | | #include "opendnp3/app/MeasurementTypes.h" |
30 | | #include "opendnp3/gen/RestartType.h" |
31 | | #include "opendnp3/logging/Logger.h" |
32 | | #include "opendnp3/master/CommandResultCallbackT.h" |
33 | | #include "opendnp3/master/CommandSet.h" |
34 | | #include "opendnp3/master/IMasterApplication.h" |
35 | | #include "opendnp3/master/RestartOperationResult.h" |
36 | | |
37 | | #include <ser4cpp/container/Buffer.h> |
38 | | |
39 | | #include <exe4cpp/Timer.h> |
40 | | #include <exe4cpp/asio/StrandExecutor.h> |
41 | | |
42 | | #include <deque> |
43 | | #include <memory> |
44 | | |
45 | | namespace opendnp3 |
46 | | { |
47 | | /* |
48 | | All of the mutable state and configuration for a master |
49 | | */ |
50 | | class MContext final : public IUpperLayer, public std::enable_shared_from_this<MContext>, private IMasterTaskRunner, private Uncopyable |
51 | | { |
52 | | private: |
53 | | MContext(const Addresses& addresses, |
54 | | const Logger& logger, |
55 | | const std::shared_ptr<exe4cpp::IExecutor>& executor, |
56 | | std::shared_ptr<ILowerLayer> lower, |
57 | | const std::shared_ptr<ISOEHandler>& SOEHandler, |
58 | | const std::shared_ptr<IMasterApplication>& application, |
59 | | std::shared_ptr<IMasterScheduler> scheduler, |
60 | | const MasterParams& params); |
61 | | |
62 | | public: |
63 | | enum class TaskState |
64 | | { |
65 | | IDLE, |
66 | | TASK_READY, |
67 | | WAIT_FOR_RESPONSE |
68 | | }; |
69 | | |
70 | | static std::shared_ptr<MContext> Create( |
71 | | const Addresses& addresses, |
72 | | const Logger& logger, |
73 | | const std::shared_ptr<exe4cpp::IExecutor>& executor, |
74 | | std::shared_ptr<ILowerLayer> lower, |
75 | | const std::shared_ptr<ISOEHandler>& SOEHandler, |
76 | | const std::shared_ptr<IMasterApplication>& application, |
77 | | std::shared_ptr<IMasterScheduler> scheduler, |
78 | | const MasterParams& params |
79 | | ); |
80 | | |
81 | | Logger logger; |
82 | | const std::shared_ptr<exe4cpp::IExecutor> executor; |
83 | | const std::shared_ptr<ILowerLayer> lower; |
84 | | |
85 | | // ------- configuration -------- |
86 | | const Addresses addresses; |
87 | | const MasterParams params; |
88 | | const std::shared_ptr<ISOEHandler> SOEHandler; |
89 | | const std::shared_ptr<IMasterApplication> application; |
90 | | const std::shared_ptr<IMasterScheduler> scheduler; |
91 | | |
92 | | // ------- dynamic state --------- |
93 | | bool isOnline = false; |
94 | | bool isSending = false; |
95 | | AppSeqNum solSeq; |
96 | | AppSeqNum unsolSeq; |
97 | | std::shared_ptr<IMasterTask> activeTask; |
98 | | exe4cpp::Timer responseTimer; |
99 | | |
100 | | MasterTasks tasks; |
101 | | std::deque<APDUHeader> confirmQueue; |
102 | | ser4cpp::Buffer txBuffer; |
103 | | TaskState tstate; |
104 | | |
105 | | // --- implement IUpperLayer ------ |
106 | | |
107 | | bool OnLowerLayerUp() final; |
108 | | |
109 | | bool OnLowerLayerDown() final; |
110 | | |
111 | | bool OnReceive(const Message& message) final; |
112 | | |
113 | | bool OnTxReady() final; |
114 | | |
115 | | // additional virtual methods that can be overriden to implement secure authentication |
116 | | |
117 | | virtual void OnParsedHeader(const ser4cpp::rseq_t& apdu, |
118 | | const APDUResponseHeader& header, |
119 | | const ser4cpp::rseq_t& objects); |
120 | | |
121 | 6.78k | virtual void RecordLastRequest(const ser4cpp::rseq_t& apdu) {} |
122 | | |
123 | | // methods for initiating command sequences |
124 | | |
125 | | void DirectOperate(CommandSet&& commands, const CommandResultCallbackT& callback, const TaskConfig& config); |
126 | | |
127 | | void SelectAndOperate(CommandSet&& commands, const CommandResultCallbackT& callback, const TaskConfig& config); |
128 | | |
129 | | // ----- public methods used to add tasks ----- |
130 | | |
131 | | std::shared_ptr<IMasterTask> AddScan(TimeDuration period, |
132 | | const HeaderBuilderT& builder, |
133 | | std::shared_ptr<ISOEHandler> soe_handler, |
134 | | TaskConfig config = TaskConfig::Default()); |
135 | | |
136 | | std::shared_ptr<IMasterTask> AddAllObjectsScan(GroupVariationID gvId, |
137 | | TimeDuration period, |
138 | | std::shared_ptr<ISOEHandler> soe_handler, |
139 | | TaskConfig config = TaskConfig::Default()); |
140 | | |
141 | | std::shared_ptr<IMasterTask> AddClassScan(const ClassField& field, |
142 | | TimeDuration period, |
143 | | std::shared_ptr<ISOEHandler> soe_handler, |
144 | | TaskConfig config = TaskConfig::Default()); |
145 | | |
146 | | std::shared_ptr<IMasterTask> AddRangeScan(GroupVariationID gvId, |
147 | | uint16_t start, |
148 | | uint16_t stop, |
149 | | TimeDuration period, |
150 | | std::shared_ptr<ISOEHandler> soe_handler, |
151 | | TaskConfig config = TaskConfig::Default()); |
152 | | |
153 | | // ---- Single shot immediate scans ---- |
154 | | |
155 | | void Scan(const HeaderBuilderT& builder, |
156 | | std::shared_ptr<ISOEHandler> soe_handler, |
157 | | TaskConfig config = TaskConfig::Default()); |
158 | | |
159 | | void ScanAllObjects(GroupVariationID gvId, |
160 | | std::shared_ptr<ISOEHandler> soe_handler, |
161 | | TaskConfig config = TaskConfig::Default()); |
162 | | |
163 | | void ScanClasses(const ClassField& field, |
164 | | std::shared_ptr<ISOEHandler> soe_handler, |
165 | | TaskConfig config = TaskConfig::Default()); |
166 | | |
167 | | void ScanRange(GroupVariationID gvId, |
168 | | uint16_t start, |
169 | | uint16_t stop, |
170 | | std::shared_ptr<ISOEHandler> soe_handler, |
171 | | TaskConfig config = TaskConfig::Default()); |
172 | | |
173 | | /// ---- Write tasks ----- |
174 | | |
175 | | void Write(const TimeAndInterval& value, uint16_t index, TaskConfig config = TaskConfig::Default()); |
176 | | |
177 | | void Restart(RestartType op, const RestartOperationCallbackT& callback, TaskConfig config = TaskConfig::Default()); |
178 | | |
179 | | void PerformFunction(const std::string& name, |
180 | | FunctionCode func, |
181 | | const HeaderBuilderT& builder, |
182 | | TaskConfig config = TaskConfig::Default()); |
183 | | |
184 | | /// public state manipulation actions |
185 | | |
186 | | TaskState ResumeActiveTask(); |
187 | | |
188 | | void CompleteActiveTask(); |
189 | | |
190 | | void QueueConfirm(const APDUHeader& header); |
191 | | |
192 | | void StartResponseTimer(); |
193 | | |
194 | | void ProcessAPDU(const APDUResponseHeader& header, const ser4cpp::rseq_t& objects); |
195 | | |
196 | | bool CheckConfirmTransmit(); |
197 | | |
198 | | void ProcessResponse(const APDUResponseHeader& header, const ser4cpp::rseq_t& objects); |
199 | | |
200 | | void ProcessUnsolicitedResponse(const APDUResponseHeader& header, const ser4cpp::rseq_t& objects); |
201 | | |
202 | | void Transmit(const ser4cpp::rseq_t& data); |
203 | | |
204 | | private: |
205 | | // --- implement IMasterTaskRunner ------ |
206 | | |
207 | | virtual bool Run(const std::shared_ptr<IMasterTask>& task) override; |
208 | | |
209 | | void ScheduleRecurringPollTask(const std::shared_ptr<IMasterTask>& task); |
210 | | |
211 | | void ProcessIIN(const IINField& iin); |
212 | | |
213 | | void OnResponseTimeout(); |
214 | | |
215 | | protected: |
216 | | void ScheduleAdhocTask(const std::shared_ptr<IMasterTask>& task); |
217 | | |
218 | | // state switch lookups |
219 | | |
220 | | TaskState OnTransmitComplete(); |
221 | | TaskState OnResponseEvent(const APDUResponseHeader& header, const ser4cpp::rseq_t& objects); |
222 | | TaskState OnResponseTimeoutEvent(); |
223 | | |
224 | | // --- state handling functions ---- |
225 | | TaskState StartTask_TaskReady(); |
226 | | TaskState OnResponse_WaitForResponse(const APDUResponseHeader& header, const ser4cpp::rseq_t& objects); |
227 | | TaskState OnResponseTimeout_WaitForResponse(); |
228 | | }; |
229 | | |
230 | | } // namespace opendnp3 |
231 | | |
232 | | #endif |