Coverage Report

Created: 2026-01-17 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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