20
20
#import " MTRLogging_Internal.h"
21
21
#import " MTRServerAttribute_Internal.h"
22
22
#import " MTRServerEndpoint_Internal.h"
23
+ #import " MTRUnfairLock.h"
23
24
#import " NSDataSpanConversion.h"
25
+
24
26
#import < Matter/MTRServerAttribute.h>
25
27
26
28
#include < app/reporting/reporting.h>
32
34
33
35
MTR_DIRECT_MEMBERS
34
36
@implementation MTRServerAttribute {
37
+ // _lock always protects access to _deviceController, _value, and _parentCluster.
38
+ // _serializedValue is protected when we are modifying it directly while we
39
+ // have no _deviceController. Once we have one, _serializedValue is only
40
+ // modified on the Matter thread.
41
+ MTRUnfairLock _lock;
35
42
MTRDeviceController * __weak _deviceController;
43
+ NSDictionary <NSString *, id > * _value;
44
+ app::ConcreteClusterPath _parentCluster;
36
45
}
37
46
38
47
- (nullable instancetype )initAttributeWithID : (NSNumber *)attributeID initialValue : (NSDictionary <NSString *, id> *)value requiredReadPrivilege : (MTRAccessControlEntryPrivilege)requiredReadPrivilege writable : (BOOL )writable
@@ -121,7 +130,10 @@ - (BOOL)setValueInternal:(NSDictionary<NSString *, id> *)value logIfNotAssociate
121
130
}
122
131
}
123
132
124
- // We serialized properly, so should be good to go on the value.
133
+ // We serialized properly, so should be good to go on the value. Lock
134
+ // around our ivar accesses.
135
+ MTRAutoUnfairLock lock (_lock);
136
+
125
137
_value = [value copy ];
126
138
127
139
MTRDeviceController * deviceController = _deviceController;
@@ -147,8 +159,16 @@ - (BOOL)setValueInternal:(NSDictionary<NSString *, id> *)value logIfNotAssociate
147
159
return YES ;
148
160
}
149
161
162
+ - (NSDictionary <NSString *, id> *)value
163
+ {
164
+ MTRAutoUnfairLock lock (_lock);
165
+ return [_value copy ];
166
+ }
167
+
150
168
- (BOOL )associateWithController : (nullable MTRDeviceController *)controller
151
169
{
170
+ MTRAutoUnfairLock lock (_lock);
171
+
152
172
MTRDeviceController * existingController = _deviceController;
153
173
if (existingController != nil ) {
154
174
#if MTR_PER_CONTROLLER_STORAGE_ENABLED
@@ -167,7 +187,34 @@ - (BOOL)associateWithController:(nullable MTRDeviceController *)controller
167
187
168
188
- (void )invalidate
169
189
{
190
+ MTRAutoUnfairLock lock (_lock);
191
+
170
192
_deviceController = nil ;
171
193
}
172
194
195
+ - (BOOL )addToCluster : (const app::ConcreteClusterPath &)cluster
196
+ {
197
+ MTRAutoUnfairLock lock (_lock);
198
+
199
+ if (_parentCluster.mClusterId != kInvalidClusterId ) {
200
+ MTR_LOG_ERROR (" Cannot add attribute to cluster " ChipLogFormatMEI " ; already added to cluster " ChipLogFormatMEI, ChipLogValueMEI (cluster.mClusterId ), ChipLogValueMEI (_parentCluster.mClusterId ));
201
+ return NO ;
202
+ }
203
+
204
+ _parentCluster = cluster;
205
+ return YES ;
206
+ }
207
+
208
+ - (void )updateParentCluster : (const app::ConcreteClusterPath &)cluster
209
+ {
210
+ MTRAutoUnfairLock lock (_lock);
211
+ _parentCluster = cluster;
212
+ }
213
+
214
+ - (const chip::app::ConcreteClusterPath &)parentCluster
215
+ {
216
+ MTRAutoUnfairLock lock (_lock);
217
+ return _parentCluster;
218
+ }
219
+
173
220
@end
0 commit comments