2424#import " MTRDeviceDataValidation.h"
2525#import " MTREndpointInfo_Internal.h"
2626#import " MTRLogging_Internal.h"
27+ #import " MTRNetworkInterfaceInfo_Internal.h"
2728#import " MTRProductIdentity.h"
2829#import " MTRUtilities.h"
2930
@@ -37,6 +38,8 @@ @implementation MTRCommissioneeInfo
3738
3839- (instancetype )initWithCommissioningInfo : (const chip::Controller::ReadCommissioningInfo &)info commissioningParameters : (MTRCommissioningParameters *)commissioningParameters
3940{
41+ using namespace chip ::app;
42+
4043 self = [super init ];
4144 _productIdentity = [[MTRProductIdentity alloc ] initWithVendorID: @(info.basic.vendorId) productID: @(info.basic.productId)];
4245
@@ -47,13 +50,15 @@ - (instancetype)initWithCommissioningInfo:(const chip::Controller::ReadCommissio
4750 }
4851 }
4952
53+ NSMutableArray <MTRNetworkInterfaceInfo *> * networkInterfaces = [[NSMutableArray alloc ] init ];
54+
5055 if (info.attributes != nullptr ) {
5156 NSMutableDictionary <MTRAttributePath *, NSDictionary <NSString *, id > *> * attributes = [[NSMutableDictionary alloc ] init ];
5257
5358 // Only expose attributes that match pathFilters, so that API consumers
5459 // don't start relying on undocumented internal details of which paths
5560 // we read from the device in which circumstances.
56- std::vector<chip::app:: AttributePathParams> pathFilters;
61+ std::vector<AttributePathParams> pathFilters;
5762 if (commissioningParameters.extraAttributesToRead != nil ) {
5863 for (MTRAttributeRequestPath * requestPath in commissioningParameters.extraAttributesToRead ) {
5964 [requestPath convertToAttributePathParams: pathFilters.emplace_back ()];
@@ -64,7 +69,7 @@ - (instancetype)initWithCommissioningInfo:(const chip::Controller::ReadCommissio
6469 // attributes, using a wildcard-endpoint path.
6570 pathFilters.emplace_back (MTRClusterIDTypeNetworkCommissioningID, MTRAttributeIDTypeGlobalAttributeFeatureMapID);
6671
67- info.attributes ->ForEachAttribute ([&](const chip::app:: ConcreteAttributePath & path) -> CHIP_ERROR {
72+ info.attributes ->ForEachAttribute ([&](const ConcreteAttributePath & path) -> CHIP_ERROR {
6873 // Only grab paths that are included in extraAttributesToRead so that
6974 // API consumers don't develop dependencies on implementation details
7075 // (like which other attributes we happen to read).
@@ -111,14 +116,42 @@ - (instancetype)initWithCommissioningInfo:(const chip::Controller::ReadCommissio
111116 });
112117
113118 _attributes = attributes;
119+
120+ // Now grab the Network Commissioning information in a nicer form.
121+ info.attributes ->ForEachAttribute (MTRClusterIDTypeNetworkCommissioningID, [&](const ConcreteAttributePath & path) -> CHIP_ERROR {
122+ if (path.mAttributeId != MTRAttributeIDTypeGlobalAttributeFeatureMapID) {
123+ return CHIP_NO_ERROR;
124+ }
125+
126+ uint32_t value;
127+ CHIP_ERROR err = info.attributes ->Get <Clusters::NetworkCommissioning::Attributes::FeatureMap::TypeInfo>(path, value);
128+ if (err != CHIP_NO_ERROR) {
129+ // Keep iterating no matter what.
130+ return CHIP_NO_ERROR;
131+ }
132+
133+ MTRNetworkInterfaceInfo * _Nullable interfaceInfo = [[MTRNetworkInterfaceInfo alloc ] initWithEndpointID: @(path.mEndpointId ) featureMap: @(value)];
134+ if (!interfaceInfo) {
135+ // Invalid feature map. Just keep looking for other ones.
136+ return CHIP_NO_ERROR;
137+ }
138+
139+ [networkInterfaces addObject: interfaceInfo];
140+ return CHIP_NO_ERROR;
141+ });
114142 }
115143
144+ auto * endpointDescriptor = [[NSSortDescriptor alloc ] initWithKey: @" endpointID" ascending: YES ];
145+ [networkInterfaces sortUsingDescriptors: @[ endpointDescriptor ]];
146+ _networkInterfaces = networkInterfaces;
147+
116148 return self;
117149}
118150
119151static NSString * const sProductIdentityCodingKey = @" pi" ;
120152static NSString * const sEndpointsCodingKey = @" ep" ;
121153static NSString * const sAttributesCodingKey = @" at" ;
154+ static NSString * const sNetworkInterfacesCodingKey = @" ni" ;
122155
123156- (nullable instancetype )initWithCoder : (NSCoder *)coder
124157{
@@ -156,6 +189,15 @@ - (nullable instancetype)initWithCoder:(NSCoder *)coder
156189 }
157190 }
158191
192+ // Decode network interface array (may be nil if decoding something encoded
193+ // before we added these properties).
194+ _networkInterfaces = [coder decodeArrayOfObjectsOfClass: MTRNetworkInterfaceInfo.class forKey :sNetworkInterfacesCodingKey ];
195+
196+ // Provide empty array for backward compatibility if not present in encoded data
197+ if (_networkInterfaces == nil ) {
198+ _networkInterfaces = @[];
199+ }
200+
159201 return self;
160202}
161203
@@ -164,6 +206,7 @@ - (void)encodeWithCoder:(NSCoder *)coder
164206 [coder encodeObject: _productIdentity forKey: sProductIdentityCodingKey ];
165207 [coder encodeObject: _endpointsById forKey: sEndpointsCodingKey ];
166208 [coder encodeObject: _attributes forKey: sAttributesCodingKey ];
209+ [coder encodeObject: _networkInterfaces forKey: sNetworkInterfacesCodingKey ];
167210}
168211
169212+ (BOOL )supportsSecureCoding
@@ -183,6 +226,7 @@ - (BOOL)isEqual:(id)object
183226 VerifyOrReturnValue (MTREqualObjects (_productIdentity, other->_productIdentity ), NO );
184227 VerifyOrReturnValue (MTREqualObjects (_endpointsById, other->_endpointsById ), NO );
185228 VerifyOrReturnValue (MTREqualObjects (_attributes, other->_attributes ), NO );
229+ VerifyOrReturnValue (MTREqualObjects (_networkInterfaces, other->_networkInterfaces ), NO );
186230
187231 return YES ;
188232}
0 commit comments