forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFailSafeContext.h
155 lines (130 loc) · 5.5 KB
/
FailSafeContext.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
*
* Copyright (c) 2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* A 'Fail Safe Context' SHALL be created on the receiver, to track fail-safe
* state information while the fail-safe is armed.
*/
#pragma once
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <system/SystemClock.h>
namespace chip {
namespace app {
class FailSafeContext
{
public:
// ===== Members for internal use by other Device Layer components.
/**
* @brief
* Only a single fail-safe timer is started on the device, if this function is called again
* when the fail-safe timer is currently armed, the currently-running fail-safe timer will
* first be cancelled, then the fail-safe timer will be re-armed.
*/
CHIP_ERROR ArmFailSafe(FabricIndex accessingFabricIndex, System::Clock::Seconds16 expiryLengthSeconds);
/**
* @brief Cleanly disarm failsafe timer, such as on CommissioningComplete
*/
void DisarmFailSafe();
void SetAddNocCommandInvoked(FabricIndex nocFabricIndex)
{
mAddNocCommandHasBeenInvoked = true;
mFabricIndex = nocFabricIndex;
}
void SetUpdateNocCommandInvoked() { mUpdateNocCommandHasBeenInvoked = true; }
void SetAddTrustedRootCertInvoked() { mAddTrustedRootCertHasBeenInvoked = true; }
void SetCsrRequestForUpdateNoc(bool isForUpdateNoc) { mIsCsrRequestForUpdateNoc = isForUpdateNoc; }
/**
* @brief
* Schedules a work to cleanup the FailSafe Context asynchronously after various cleanup work
* has completed.
*/
void ScheduleFailSafeCleanup(FabricIndex fabricIndex, bool addNocCommandInvoked, bool updateNocCommandInvoked);
bool IsFailSafeArmed(FabricIndex accessingFabricIndex) const
{
return IsFailSafeArmed() && MatchesFabricIndex(accessingFabricIndex);
}
// Returns true if the fail-safe is in a state where commands that require an armed
// fail-safe can no longer execute, but a new fail-safe can't be armed yet.
bool IsFailSafeBusy() const { return mFailSafeBusy; }
bool IsFailSafeArmed() const { return mFailSafeArmed; }
// True if it is possible to do an initial arming of the failsafe if needed.
// To be used in places where some action should take place only if the
// fail-safe could be armed after that action.
bool IsFailSafeFullyDisarmed() const { return !IsFailSafeArmed() && !IsFailSafeBusy(); }
bool MatchesFabricIndex(FabricIndex accessingFabricIndex) const
{
VerifyOrDie(IsFailSafeArmed());
return (accessingFabricIndex == mFabricIndex);
}
bool NocCommandHasBeenInvoked() const { return mAddNocCommandHasBeenInvoked || mUpdateNocCommandHasBeenInvoked; }
bool AddNocCommandHasBeenInvoked() const { return mAddNocCommandHasBeenInvoked; }
bool UpdateNocCommandHasBeenInvoked() const { return mUpdateNocCommandHasBeenInvoked; }
bool AddTrustedRootCertHasBeenInvoked() const { return mAddTrustedRootCertHasBeenInvoked; }
bool IsCsrRequestForUpdateNoc() const { return mIsCsrRequestForUpdateNoc; }
FabricIndex GetFabricIndex() const
{
VerifyOrDie(IsFailSafeArmed());
return mFabricIndex;
}
// Immediately disarms the timer and schedules a failsafe timer expiry.
// If the failsafe is not armed, this is a no-op.
void ForceFailSafeTimerExpiry();
private:
bool mFailSafeArmed = false;
bool mFailSafeBusy = false;
bool mAddNocCommandHasBeenInvoked = false;
bool mUpdateNocCommandHasBeenInvoked = false;
bool mAddTrustedRootCertHasBeenInvoked = false;
// The fact of whether a CSR occurred at all is stored elsewhere.
bool mIsCsrRequestForUpdateNoc = false;
FabricIndex mFabricIndex = kUndefinedFabricIndex;
/**
* @brief
* The callback function to be called when "fail-safe timer" expires.
*/
static void HandleArmFailSafeTimer(System::Layer * layer, void * aAppState);
/**
* @brief
* The callback function to be called when max cumulative time expires.
*/
static void HandleMaxCumulativeFailSafeTimer(System::Layer * layer, void * aAppState);
/**
* @brief
* The callback function to be called asynchronously after various cleanup work has completed
* to actually disarm the fail-safe.
*/
static void HandleDisarmFailSafe(intptr_t arg);
void SetFailSafeArmed(bool armed);
/**
* @brief Reset to unarmed basic state
*/
void ResetState()
{
SetFailSafeArmed(false);
mAddNocCommandHasBeenInvoked = false;
mUpdateNocCommandHasBeenInvoked = false;
mAddTrustedRootCertHasBeenInvoked = false;
mFailSafeBusy = false;
mIsCsrRequestForUpdateNoc = false;
}
void FailSafeTimerExpired();
CHIP_ERROR CommitToStorage();
};
} // namespace app
} // namespace chip