Skip to content

Commit

Permalink
Add ObjC Thread Operational Dataset (#8172)
Browse files Browse the repository at this point in the history
* Add an ObjC wrapper for the CHIP Thread Operational Dataset

* Restyled by clang-format

* Address review comments

* Restyled by clang-format

* address comments

* Restyled by clang-format

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
sagar-apple and restyled-commits authored Jul 8, 2021
1 parent d2f2409 commit e55ad30
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/darwin/Framework/CHIP.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
991DC0892475F47D00C13860 /* CHIPDeviceController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 991DC0872475F47D00C13860 /* CHIPDeviceController.mm */; };
991DC08B247704DC00C13860 /* CHIPLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 991DC08A247704DC00C13860 /* CHIPLogging.h */; };
9956064426420367000C28DE /* CHIPSetupPayload_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9956064326420367000C28DE /* CHIPSetupPayload_Internal.h */; };
997DED162695343400975E97 /* CHIPThreadOperationalDataset.mm in Sources */ = {isa = PBXBuildFile; fileRef = 997DED152695343400975E97 /* CHIPThreadOperationalDataset.mm */; };
997DED182695344800975E97 /* CHIPThreadOperationalDataset.h in Headers */ = {isa = PBXBuildFile; fileRef = 997DED172695344800975E97 /* CHIPThreadOperationalDataset.h */; settings = {ATTRIBUTES = (Public, ); }; };
997DED1A26955D0200975E97 /* CHIPThreadOperationalDatasetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 997DED1926955D0200975E97 /* CHIPThreadOperationalDatasetTests.mm */; };
99C65E10267282F1003402F6 /* CHIPControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 99C65E0F267282F1003402F6 /* CHIPControllerTests.m */; };
B20252972459E34F00F97062 /* CHIP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B202528D2459E34F00F97062 /* CHIP.framework */; };
B289D4212639C0D300D4E314 /* CHIPOnboardingPayloadParser.h in Headers */ = {isa = PBXBuildFile; fileRef = B289D41F2639C0D300D4E314 /* CHIPOnboardingPayloadParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -127,6 +130,9 @@
991DC0872475F47D00C13860 /* CHIPDeviceController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPDeviceController.mm; sourceTree = "<group>"; };
991DC08A247704DC00C13860 /* CHIPLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPLogging.h; sourceTree = "<group>"; };
9956064326420367000C28DE /* CHIPSetupPayload_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPSetupPayload_Internal.h; sourceTree = "<group>"; };
997DED152695343400975E97 /* CHIPThreadOperationalDataset.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPThreadOperationalDataset.mm; sourceTree = "<group>"; };
997DED172695344800975E97 /* CHIPThreadOperationalDataset.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPThreadOperationalDataset.h; sourceTree = "<group>"; };
997DED1926955D0200975E97 /* CHIPThreadOperationalDatasetTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPThreadOperationalDatasetTests.mm; sourceTree = "<group>"; };
99C65E0F267282F1003402F6 /* CHIPControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CHIPControllerTests.m; sourceTree = "<group>"; };
B202528D2459E34F00F97062 /* CHIP.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CHIP.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B20252912459E34F00F97062 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -243,6 +249,8 @@
2C222ACE255C620600E446B9 /* CHIPDevice.h */,
2C222ACF255C620600E446B9 /* CHIPDevice.mm */,
2C8C8FBE253E0C2100797F05 /* CHIPPersistentStorageDelegate.h */,
997DED152695343400975E97 /* CHIPThreadOperationalDataset.mm */,
997DED172695344800975E97 /* CHIPThreadOperationalDataset.h */,
2C8C8FBD253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.h */,
2C8C8FBF253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.mm */,
2CB7163E252F731E0026E2BB /* CHIPDevicePairingDelegate.h */,
Expand Down Expand Up @@ -274,6 +282,7 @@
1EB41B7A263C4CC60048E4C1 /* CHIPClustersTests.m */,
99C65E0F267282F1003402F6 /* CHIPControllerTests.m */,
B2F53AF1245B0DCF0010745E /* CHIPSetupPayloadParserTests.m */,
997DED1926955D0200975E97 /* CHIPThreadOperationalDatasetTests.mm */,
B202529D2459E34F00F97062 /* Info.plist */,
);
path = CHIPTests;
Expand Down Expand Up @@ -304,6 +313,7 @@
B2E0D7B2245B0B5C003C5B48 /* CHIPManualSetupPayloadParser.h in Headers */,
B2E0D7B1245B0B5C003C5B48 /* CHIP.h in Headers */,
B2E0D7B8245B0B5C003C5B48 /* CHIPSetupPayload.h in Headers */,
997DED182695344800975E97 /* CHIPThreadOperationalDataset.h in Headers */,
9956064426420367000C28DE /* CHIPSetupPayload_Internal.h in Headers */,
2C8C8FC1253E0C2100797F05 /* CHIPPersistentStorageDelegate.h in Headers */,
B2E0D7B5245B0B5C003C5B48 /* CHIPQRCodeSetupPayloadParser.h in Headers */,
Expand Down Expand Up @@ -438,6 +448,7 @@
files = (
2C8C8FC2253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.mm in Sources */,
2CB7163C252E8A7C0026E2BB /* CHIPDevicePairingDelegateBridge.mm in Sources */,
997DED162695343400975E97 /* CHIPThreadOperationalDataset.mm in Sources */,
1E85732426551A490050A4D9 /* attribute-list-byte-span.cpp in Sources */,
1E85730E265519AE0050A4D9 /* CHIPClusters.cpp in Sources */,
1E85732326551A490050A4D9 /* process-global-message.cpp in Sources */,
Expand Down Expand Up @@ -481,6 +492,7 @@
buildActionMask = 2147483647;
files = (
1EB41B7B263C4CC60048E4C1 /* CHIPClustersTests.m in Sources */,
997DED1A26955D0200975E97 /* CHIPThreadOperationalDatasetTests.mm in Sources */,
99C65E10267282F1003402F6 /* CHIPControllerTests.m in Sources */,
B2F53AF2245B0DCF0010745E /* CHIPSetupPayloadParserTests.m in Sources */,
);
Expand Down Expand Up @@ -630,7 +642,6 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = CHIPTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down
1 change: 1 addition & 0 deletions src/darwin/Framework/CHIP/CHIP.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#import <CHIP/CHIPPersistentStorageDelegate.h>
#import <CHIP/CHIPQRCodeSetupPayloadParser.h>
#import <CHIP/CHIPSetupPayload.h>
#import <CHIP/CHIPThreadOperationalDataset.h>

#import <Foundation/Foundation.h>
//! Project version number for CHIP.
Expand Down
81 changes: 81 additions & 0 deletions src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
*
* Copyright (c) 2021 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.
*/

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface CHIPThreadOperationalDataset : NSObject

/**
* The expected lengths of each of the NSData fields in the CHIPThreadOperationalDataset
*
* initWithNetworkName must be provided NSData fields with at least these lengths otherwise
* the object will fail to init.
*/
extern size_t const CHIPSizeThreadNetworkName;
extern size_t const CHIPSizeThreadExtendedPanId;
extern size_t const CHIPSizeThreadMasterKey;
extern size_t const CHIPSizeThreadPSKc;

/**
* The Thread Network name
*/
@property (nonatomic, nullable, readwrite) NSString * networkName;
/**
* The Thread Network extendended PAN ID
*/
@property (nonatomic, nullable, readwrite) NSData * extendedPANID;
/**
* The 16 byte Master Key
*/
@property (nonatomic, nullable, readwrite) NSData * masterKey;
/**
* The Thread PSKc
*/
@property (nonatomic, nullable, readwrite) NSData * PSKc;
/**
* The Thread network channel
*/
@property (nonatomic, readwrite) uint16_t channel;
/**
* The Thread PAN ID
*/
@property (nonatomic, nullable, readwrite) NSData * panID;

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

/**
* Create a Thread Operational Dataset object with the individual network fields.
* This initializer will return nil if any of the NSData fields are smaller than expected.
*/
- (nullable instancetype)initWithNetworkName:(NSString *)networkName
extendedPANID:(NSData *)extendedPANID
masterKey:(NSData *)masterKey
PSKc:(NSData *)PSKc
channel:(uint16_t)channel
panID:(NSData *)panID;

/**
* Get the underlying data that represents the Thread Active Operational Dataset
*/
- (NSData *)asData;

@end

NS_ASSUME_NONNULL_END
119 changes: 119 additions & 0 deletions src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
*
* Copyright (c) 2021 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.
*/

#import "CHIPThreadOperationalDataset.h"

#include "CHIPLogging.h"
#include <support/Span.h>
#include <support/ThreadOperationalDataset.h>

size_t const CHIPSizeThreadNetworkName = chip::Thread::kSizeNetworkName;
size_t const CHIPSizeThreadExtendedPanId = chip::Thread::kSizeExtendedPanId;
size_t const CHIPSizeThreadMasterKey = chip::Thread::kSizeMasterKey;
size_t const CHIPSizeThreadPSKc = chip::Thread::kSizePSKc;

@interface CHIPThreadOperationalDataset ()

@property (readonly) chip::Thread::OperationalDataset cppThreadOperationalDataset;

@end

@implementation CHIPThreadOperationalDataset

- (nullable instancetype)initWithNetworkName:(NSString *)networkName
extendedPANID:(NSData *)extendedPANID
masterKey:(NSData *)masterKey
PSKc:(NSData *)PSKc
channel:(uint16_t)channel
panID:(NSData *)panID
{
if (self = [super init]) {
_networkName = networkName;
_extendedPANID = extendedPANID;
_masterKey = masterKey;
_PSKc = PSKc;
_channel = channel;
_panID = panID;
_cppThreadOperationalDataset = chip::Thread::OperationalDataset();
if ([self _populateCppOperationalDataset]) {
return self;
}
}
return nil;
}

- (BOOL)_populateCppOperationalDataset
{
_cppThreadOperationalDataset.Clear();
_cppThreadOperationalDataset.SetNetworkName([self.networkName cStringUsingEncoding:NSUTF8StringEncoding]);

if (![self _checkDataLength:self.extendedPANID expectedLength:chip::Thread::kSizeExtendedPanId]) {
CHIP_LOG_ERROR("Invalid ExtendedPANID");
return NO;
}
uint8_t extendedPanId[chip::Thread::kSizeExtendedPanId];
[self.extendedPANID getBytes:&extendedPanId length:chip::Thread::kSizeExtendedPanId];
_cppThreadOperationalDataset.SetExtendedPanId(extendedPanId);

if (![self _checkDataLength:self.masterKey expectedLength:chip::Thread::kSizeMasterKey]) {
CHIP_LOG_ERROR("Invalid MasterKey");
return NO;
}
uint8_t masterKey[chip::Thread::kSizeMasterKey];
[self.masterKey getBytes:&masterKey length:chip::Thread::kSizeMasterKey];
_cppThreadOperationalDataset.SetMasterKey(masterKey);

if (![self _checkDataLength:self.PSKc expectedLength:chip::Thread::kSizePSKc]) {
CHIP_LOG_ERROR("Invalid PKSc");
return NO;
}
uint8_t PSKc[chip::Thread::kSizePSKc];
[self.PSKc getBytes:&PSKc length:chip::Thread::kSizePSKc];
_cppThreadOperationalDataset.SetPSKc(PSKc);

_cppThreadOperationalDataset.SetChannel(self.channel);

// Thread's PAN ID is 2 bytes
if (![self _checkDataLength:self.panID expectedLength:2]) {
CHIP_LOG_ERROR("Invalid PAN ID");
return NO;
}
uint16_t * valuePtr = (uint16_t *) [self.panID bytes];
if (valuePtr == nullptr) {
return NO;
}
_cppThreadOperationalDataset.SetPanId(*valuePtr);

return YES;
}

- (BOOL)_checkDataLength:(NSData *)data expectedLength:(size_t)expectedLength
{
if (data.length != expectedLength) {
CHIP_LOG_ERROR("Length Check Failed. Length:%tu is too short, must be at least %tu", data.length, expectedLength);
return NO;
}
return YES;
}

- (NSData *)asData
{
chip::ByteSpan span = _cppThreadOperationalDataset.AsByteSpan();
return [NSData dataWithBytes:span.data() length:span.size()];
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// CHIPControllerTests.m
// CHIPControllerTests
/**
*
* Copyright (c) 2021 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.
*/

#import <CHIP/CHIP.h>

// system dependencies
#import <XCTest/XCTest.h>

@interface CHIPThreadOperationalDatasetTests : XCTestCase

@end

@implementation CHIPThreadOperationalDatasetTests

- (void)testThreadOperationalDataset
{
const unsigned char extendedPANID[] = { 0x68, 0x09, 0x45, 0x04, 0xae, 0xef, 0x42, 0x67 };
const unsigned char masterKey[]
= { 0x7c, 0x77, 0x08, 0x70, 0xeb, 0x05, 0xcc, 0x6d, 0xbe, 0xcc, 0x6d, 0x62, 0x32, 0xea, 0xb8, 0xb9 };
const unsigned char PKSc[] = { 0xc4, 0xa3, 0x81, 0x25, 0x94, 0x77, 0x81, 0x99, 0x6e, 0xf5, 0x61, 0xdf, 0x8f, 0xb7, 0x8d, 0x23 };
const uint16_t panID = 0x28f4;
CHIPThreadOperationalDataset * dataset = [[CHIPThreadOperationalDataset alloc]
initWithNetworkName:@"TestNetwork"
extendedPANID:[NSData dataWithBytes:&extendedPANID length:CHIPSizeThreadExtendedPanId]
masterKey:[NSData dataWithBytes:&masterKey length:CHIPSizeThreadMasterKey]
PSKc:[NSData dataWithBytes:&PKSc length:CHIPSizeThreadPSKc]
channel:25
panID:[NSData dataWithBytes:&panID length:sizeof(panID)]];
XCTAssertNotNil(dataset);
NSData * data = [dataset asData];
XCTAssertNotNil(data);
}

- (void)testThreadOperationalDatasetInvalid
{
const unsigned char extendedPANID[] = { 0x67 };
const unsigned char masterKey[] = {};
const unsigned char PKSc[] = { 0xb7, 0x8d, 0x23 };
const uint16_t panID = 0x0;
CHIPThreadOperationalDataset * dataset =
[[CHIPThreadOperationalDataset alloc] initWithNetworkName:@"TestNetwork"
extendedPANID:[NSData dataWithBytes:&extendedPANID length:sizeof(extendedPANID)]
masterKey:[NSData dataWithBytes:&masterKey length:sizeof(masterKey)]
PSKc:[NSData dataWithBytes:&PKSc length:sizeof(PKSc)]
channel:25
panID:[NSData dataWithBytes:&panID length:sizeof(panID)]];

XCTAssertNil(dataset);
}

@end

0 comments on commit e55ad30

Please sign in to comment.