From 5d3695b2f986b83bde389761d9f115325f08ebdb Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Thu, 22 Jul 2021 14:49:10 -0700 Subject: [PATCH] [Darwin] Fix incorrect Thread panID generation (#8562) * [Darwin] Fix incorrect Thread panID generation * Fix restyled issue Co-authored-by: Boris Zbarsky --- .../CHIP/CHIPThreadOperationalDataset.h | 6 ++++ .../CHIP/CHIPThreadOperationalDataset.mm | 35 ++++++++++++++++++- .../CHIPThreadOperationalDatasetTests.mm | 9 +++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.h b/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.h index fab019eb169c98..a3e5de59cadcf4 100644 --- a/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.h +++ b/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.h @@ -73,6 +73,12 @@ extern size_t const CHIPSizeThreadPSKc; channel:(uint16_t)channel panID:(NSData *)panID; +/** + * Create a Thread Operational Dataset object with a RCP formatted active operational dataset. + * This initializer will return nil if the input data cannot be parsed correctly + */ +- (nullable instancetype)initWithData:(NSData *)data; + /** * Get the underlying data that represents the Thread Active Operational Dataset */ diff --git a/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.mm b/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.mm index b48dcb0dc647bb..0f48e2ed37ce42 100644 --- a/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.mm +++ b/src/darwin/Framework/CHIP/CHIPThreadOperationalDataset.mm @@ -96,7 +96,8 @@ - (BOOL)_populateCppOperationalDataset if (valuePtr == nullptr) { return NO; } - _cppThreadOperationalDataset.SetPanId(*valuePtr); + // The underlying CPP class assumes Big Endianness for the panID + _cppThreadOperationalDataset.SetPanId(CFSwapInt16HostToBig(*valuePtr)); return YES; } @@ -110,6 +111,38 @@ - (BOOL)_checkDataLength:(NSData *)data expectedLength:(size_t)expectedLength return YES; } +- (nullable instancetype)initWithData:(NSData *)data +{ + chip::ByteSpan span = chip::ByteSpan((uint8_t *) data.bytes, data.length); + auto dataset = chip::Thread::OperationalDataset(); + CHIP_ERROR error = dataset.Init(span); + if (error != CHIP_NO_ERROR) { + CHIP_LOG_ERROR("Failed to parse data, cannot construct Operational Dataset. %d", error); + return nil; + } + // len+1 for null termination + char networkName[CHIPSizeThreadNetworkName + 1]; + uint8_t pskc[CHIPSizeThreadPSKc]; + uint8_t extendedPANID[CHIPSizeThreadExtendedPanId]; + uint8_t masterKey[CHIPSizeThreadMasterKey]; + uint16_t panID; + uint16_t channel; + dataset.GetNetworkName(networkName); + dataset.GetExtendedPanId(extendedPANID); + dataset.GetMasterKey(masterKey); + dataset.GetPSKc(pskc); + dataset.GetPanId(panID); + dataset.GetChannel(channel); + panID = CFSwapInt16BigToHost(panID); + + return [self initWithNetworkName:[NSString stringWithUTF8String:networkName] + extendedPANID:[NSData dataWithBytes:extendedPANID length:CHIPSizeThreadExtendedPanId] + masterKey:[NSData dataWithBytes:masterKey length:CHIPSizeThreadMasterKey] + PSKc:[NSData dataWithBytes:pskc length:CHIPSizeThreadPSKc] + channel:channel + panID:[NSData dataWithBytes:&panID length:sizeof(uint16_t)]]; +} + - (NSData *)asData { chip::ByteSpan span = _cppThreadOperationalDataset.AsByteSpan(); diff --git a/src/darwin/Framework/CHIPTests/CHIPThreadOperationalDatasetTests.mm b/src/darwin/Framework/CHIPTests/CHIPThreadOperationalDatasetTests.mm index 1f1b2390308a64..614dd319e1731d 100644 --- a/src/darwin/Framework/CHIPTests/CHIPThreadOperationalDatasetTests.mm +++ b/src/darwin/Framework/CHIPTests/CHIPThreadOperationalDatasetTests.mm @@ -46,6 +46,15 @@ - (void)testThreadOperationalDataset XCTAssertNotNil(dataset); NSData * data = [dataset asData]; XCTAssertNotNil(data); + + CHIPThreadOperationalDataset * reconstructed = [[CHIPThreadOperationalDataset alloc] initWithData:data]; + XCTAssertNotNil(reconstructed); + XCTAssertEqualObjects(reconstructed.networkName, dataset.networkName); + XCTAssertEqualObjects(reconstructed.panID, dataset.panID); + XCTAssertEqualObjects(reconstructed.masterKey, dataset.masterKey); + XCTAssertEqualObjects(reconstructed.PSKc, dataset.PSKc); + XCTAssertEqualObjects(reconstructed.extendedPANID, dataset.extendedPANID); + XCTAssertEqual(reconstructed.channel, dataset.channel); } - (void)testThreadOperationalDatasetInvalid