diff --git a/config/nrfconnect/app/enable-gnu-std.cmake b/config/nrfconnect/app/enable-gnu-std.cmake new file mode 100644 index 00000000000000..34c5f56621ca77 --- /dev/null +++ b/config/nrfconnect/app/enable-gnu-std.cmake @@ -0,0 +1,3 @@ +add_library(gnu17 INTERFACE) +target_compile_options(gnu17 INTERFACE -std=gnu++17 -D_SYS__PTHREADTYPES_H_) +target_link_libraries(app PRIVATE gnu17) diff --git a/examples/all-clusters-app/all-clusters-common/gen/attribute-size.cpp b/examples/all-clusters-app/all-clusters-common/gen/attribute-size.cpp index b52773c1f9097e..9c6e870d638c41 100644 --- a/examples/all-clusters-app/all-clusters-common/gen/attribute-size.cpp +++ b/examples/all-clusters-app/all-clusters-common/gen/attribute-size.cpp @@ -420,7 +420,7 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo { case 0x0001: // fabrics list { - entryLength = 18; + entryLength = 52; if (((index - 1) * entryLength) > (am->size - entryLength)) { ChipLogError(Zcl, "Index %l is invalid.", index); @@ -434,7 +434,15 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo copyListMember(write ? dest : (uint8_t *) &entry->VendorId, write ? (uint8_t *) &entry->VendorId : src, write, &entryOffset, sizeof(entry->VendorId)); // INT16U copyListMember(write ? dest : (uint8_t *) &entry->NodeId, write ? (uint8_t *) &entry->NodeId : src, write, &entryOffset, - sizeof(entry->NodeId)); // NODE_ID + sizeof(entry->NodeId)); // NODE_ID + chip::ByteSpan * LabelSpan = &entry->Label; // OCTET_STRING + if (CHIP_NO_ERROR != + (write ? WriteByteSpan(dest + entryOffset, 34, LabelSpan) : ReadByteSpan(src + entryOffset, 34, LabelSpan))) + { + ChipLogError(Zcl, "Index %l is invalid. Not enough remaining space", index); + return 0; + } + entryOffset = static_cast(entryOffset + 34); break; } } @@ -858,7 +866,7 @@ uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attribut { case 0x0001: // fabrics list // Struct _FabricDescriptor - entryLength = 18; + entryLength = 52; break; } break; diff --git a/examples/chip-tool/commands/clusters/Commands.h b/examples/chip-tool/commands/clusters/Commands.h index 1bbf68ab7cc61d..4a4c5d642e9fde 100644 --- a/examples/chip-tool/commands/clusters/Commands.h +++ b/examples/chip-tool/commands/clusters/Commands.h @@ -879,6 +879,7 @@ static void OnOperationalCredentialsFabricsListListAttributeResponse(void * cont ChipLogProgress(chipTool, " FabricId: %" PRIu64 "", entries[i].FabricId); ChipLogProgress(chipTool, " VendorId: %" PRIu16 "", entries[i].VendorId); ChipLogProgress(chipTool, " NodeId: %" PRIu64 "", entries[i].NodeId); + ChipLogProgress(Zcl, " Label: %zu", entries[i].Label.size()); } ModelCommand * command = reinterpret_cast(context); diff --git a/examples/lighting-app/lighting-common/gen/attribute-size.cpp b/examples/lighting-app/lighting-common/gen/attribute-size.cpp index 3f0b9b4e45338f..03252a311455e3 100644 --- a/examples/lighting-app/lighting-common/gen/attribute-size.cpp +++ b/examples/lighting-app/lighting-common/gen/attribute-size.cpp @@ -126,7 +126,7 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo { case 0x0001: // fabrics list { - entryLength = 18; + entryLength = 52; if (((index - 1) * entryLength) > (am->size - entryLength)) { ChipLogError(Zcl, "Index %l is invalid.", index); @@ -140,7 +140,15 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo copyListMember(write ? dest : (uint8_t *) &entry->VendorId, write ? (uint8_t *) &entry->VendorId : src, write, &entryOffset, sizeof(entry->VendorId)); // INT16U copyListMember(write ? dest : (uint8_t *) &entry->NodeId, write ? (uint8_t *) &entry->NodeId : src, write, &entryOffset, - sizeof(entry->NodeId)); // NODE_ID + sizeof(entry->NodeId)); // NODE_ID + chip::ByteSpan * LabelSpan = &entry->Label; // OCTET_STRING + if (CHIP_NO_ERROR != + (write ? WriteByteSpan(dest + entryOffset, 34, LabelSpan) : ReadByteSpan(src + entryOffset, 34, LabelSpan))) + { + ChipLogError(Zcl, "Index %l is invalid. Not enough remaining space", index); + return 0; + } + entryOffset = static_cast(entryOffset + 34); break; } } @@ -334,7 +342,7 @@ uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attribut { case 0x0001: // fabrics list // Struct _FabricDescriptor - entryLength = 18; + entryLength = 52; break; } break; diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index 489bec974ec8be..cf1799a78929e8 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -34,6 +34,8 @@ find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) project(chip-nrfconnect-lighting-example) +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) + target_compile_options(app PRIVATE -Werror) target_include_directories(app PRIVATE diff --git a/examples/lock-app/lock-common/gen/attribute-size.cpp b/examples/lock-app/lock-common/gen/attribute-size.cpp index 3f0b9b4e45338f..03252a311455e3 100644 --- a/examples/lock-app/lock-common/gen/attribute-size.cpp +++ b/examples/lock-app/lock-common/gen/attribute-size.cpp @@ -126,7 +126,7 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo { case 0x0001: // fabrics list { - entryLength = 18; + entryLength = 52; if (((index - 1) * entryLength) > (am->size - entryLength)) { ChipLogError(Zcl, "Index %l is invalid.", index); @@ -140,7 +140,15 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo copyListMember(write ? dest : (uint8_t *) &entry->VendorId, write ? (uint8_t *) &entry->VendorId : src, write, &entryOffset, sizeof(entry->VendorId)); // INT16U copyListMember(write ? dest : (uint8_t *) &entry->NodeId, write ? (uint8_t *) &entry->NodeId : src, write, &entryOffset, - sizeof(entry->NodeId)); // NODE_ID + sizeof(entry->NodeId)); // NODE_ID + chip::ByteSpan * LabelSpan = &entry->Label; // OCTET_STRING + if (CHIP_NO_ERROR != + (write ? WriteByteSpan(dest + entryOffset, 34, LabelSpan) : ReadByteSpan(src + entryOffset, 34, LabelSpan))) + { + ChipLogError(Zcl, "Index %l is invalid. Not enough remaining space", index); + return 0; + } + entryOffset = static_cast(entryOffset + 34); break; } } @@ -334,7 +342,7 @@ uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attribut { case 0x0001: // fabrics list // Struct _FabricDescriptor - entryLength = 18; + entryLength = 52; break; } break; diff --git a/examples/lock-app/nrfconnect/CMakeLists.txt b/examples/lock-app/nrfconnect/CMakeLists.txt index 47a8ec841ed091..a1fd9afca569a1 100644 --- a/examples/lock-app/nrfconnect/CMakeLists.txt +++ b/examples/lock-app/nrfconnect/CMakeLists.txt @@ -36,6 +36,8 @@ target_compile_options(app PRIVATE -Werror) project(chip-nrfconnect-lock-example) +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) + target_include_directories(app PRIVATE main/include ${LOCK_COMMON} diff --git a/examples/pigweed-app/nrfconnect/CMakeLists.txt b/examples/pigweed-app/nrfconnect/CMakeLists.txt index 26df06b6f58e77..f87a5485af315b 100644 --- a/examples/pigweed-app/nrfconnect/CMakeLists.txt +++ b/examples/pigweed-app/nrfconnect/CMakeLists.txt @@ -31,6 +31,8 @@ find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) project(chip-nrf52840-pigweed-example) +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) + target_compile_options(app PRIVATE -Werror) include(${PIGWEED_ROOT}/pw_build/pigweed.cmake) diff --git a/examples/pump-app/nrfconnect/CMakeLists.txt b/examples/pump-app/nrfconnect/CMakeLists.txt index fbc48a8c72f7ce..33f2d5657737ec 100644 --- a/examples/pump-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-app/nrfconnect/CMakeLists.txt @@ -30,6 +30,8 @@ target_compile_options(app PRIVATE -Werror) project(chip-nrfconnect-pump-example) +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) + target_include_directories(app PRIVATE main/include ${PUMP_COMMON} diff --git a/examples/pump-app/pump-common/gen/attribute-size.cpp b/examples/pump-app/pump-common/gen/attribute-size.cpp index 3f0b9b4e45338f..03252a311455e3 100644 --- a/examples/pump-app/pump-common/gen/attribute-size.cpp +++ b/examples/pump-app/pump-common/gen/attribute-size.cpp @@ -126,7 +126,7 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo { case 0x0001: // fabrics list { - entryLength = 18; + entryLength = 52; if (((index - 1) * entryLength) > (am->size - entryLength)) { ChipLogError(Zcl, "Index %l is invalid.", index); @@ -140,7 +140,15 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo copyListMember(write ? dest : (uint8_t *) &entry->VendorId, write ? (uint8_t *) &entry->VendorId : src, write, &entryOffset, sizeof(entry->VendorId)); // INT16U copyListMember(write ? dest : (uint8_t *) &entry->NodeId, write ? (uint8_t *) &entry->NodeId : src, write, &entryOffset, - sizeof(entry->NodeId)); // NODE_ID + sizeof(entry->NodeId)); // NODE_ID + chip::ByteSpan * LabelSpan = &entry->Label; // OCTET_STRING + if (CHIP_NO_ERROR != + (write ? WriteByteSpan(dest + entryOffset, 34, LabelSpan) : ReadByteSpan(src + entryOffset, 34, LabelSpan))) + { + ChipLogError(Zcl, "Index %l is invalid. Not enough remaining space", index); + return 0; + } + entryOffset = static_cast(entryOffset + 34); break; } } @@ -334,7 +342,7 @@ uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attribut { case 0x0001: // fabrics list // Struct _FabricDescriptor - entryLength = 18; + entryLength = 52; break; } break; diff --git a/examples/pump-controller-app/nrfconnect/CMakeLists.txt b/examples/pump-controller-app/nrfconnect/CMakeLists.txt index cf9e19dd6b66ca..b7a5d206203a30 100644 --- a/examples/pump-controller-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-controller-app/nrfconnect/CMakeLists.txt @@ -30,6 +30,8 @@ target_compile_options(app PRIVATE -Werror) project(chip-nrfconnect-pump-controller-example) +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) + target_include_directories(app PRIVATE main/include ${PUMPC_COMMON} diff --git a/examples/pump-controller-app/pump-controller-common/gen/attribute-size.cpp b/examples/pump-controller-app/pump-controller-common/gen/attribute-size.cpp index 3f0b9b4e45338f..03252a311455e3 100644 --- a/examples/pump-controller-app/pump-controller-common/gen/attribute-size.cpp +++ b/examples/pump-controller-app/pump-controller-common/gen/attribute-size.cpp @@ -126,7 +126,7 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo { case 0x0001: // fabrics list { - entryLength = 18; + entryLength = 52; if (((index - 1) * entryLength) > (am->size - entryLength)) { ChipLogError(Zcl, "Index %l is invalid.", index); @@ -140,7 +140,15 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo copyListMember(write ? dest : (uint8_t *) &entry->VendorId, write ? (uint8_t *) &entry->VendorId : src, write, &entryOffset, sizeof(entry->VendorId)); // INT16U copyListMember(write ? dest : (uint8_t *) &entry->NodeId, write ? (uint8_t *) &entry->NodeId : src, write, &entryOffset, - sizeof(entry->NodeId)); // NODE_ID + sizeof(entry->NodeId)); // NODE_ID + chip::ByteSpan * LabelSpan = &entry->Label; // OCTET_STRING + if (CHIP_NO_ERROR != + (write ? WriteByteSpan(dest + entryOffset, 34, LabelSpan) : ReadByteSpan(src + entryOffset, 34, LabelSpan))) + { + ChipLogError(Zcl, "Index %l is invalid. Not enough remaining space", index); + return 0; + } + entryOffset = static_cast(entryOffset + 34); break; } } @@ -334,7 +342,7 @@ uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attribut { case 0x0001: // fabrics list // Struct _FabricDescriptor - entryLength = 18; + entryLength = 52; break; } break; diff --git a/examples/shell/nrfconnect/CMakeLists.txt b/examples/shell/nrfconnect/CMakeLists.txt index 83cf26b62d5029..ca6a8095b82dc1 100644 --- a/examples/shell/nrfconnect/CMakeLists.txt +++ b/examples/shell/nrfconnect/CMakeLists.txt @@ -27,6 +27,8 @@ find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) project(chip-nrfconnect-shell-example) +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) + target_compile_options(app PRIVATE -Werror) target_include_directories(app PRIVATE diff --git a/examples/temperature-measurement-app/esp32/main/gen/attribute-size.cpp b/examples/temperature-measurement-app/esp32/main/gen/attribute-size.cpp index 975b49d14b733b..39e2c1a5fcaaab 100644 --- a/examples/temperature-measurement-app/esp32/main/gen/attribute-size.cpp +++ b/examples/temperature-measurement-app/esp32/main/gen/attribute-size.cpp @@ -126,7 +126,7 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo { case 0x0001: // fabrics list { - entryLength = 18; + entryLength = 52; if (((index - 1) * entryLength) > (am->size - entryLength)) { ChipLogError(Zcl, "Index %l is invalid.", index); @@ -140,7 +140,15 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo copyListMember(write ? dest : (uint8_t *) &entry->VendorId, write ? (uint8_t *) &entry->VendorId : src, write, &entryOffset, sizeof(entry->VendorId)); // INT16U copyListMember(write ? dest : (uint8_t *) &entry->NodeId, write ? (uint8_t *) &entry->NodeId : src, write, &entryOffset, - sizeof(entry->NodeId)); // NODE_ID + sizeof(entry->NodeId)); // NODE_ID + chip::ByteSpan * LabelSpan = &entry->Label; // OCTET_STRING + if (CHIP_NO_ERROR != + (write ? WriteByteSpan(dest + entryOffset, 34, LabelSpan) : ReadByteSpan(src + entryOffset, 34, LabelSpan))) + { + ChipLogError(Zcl, "Index %l is invalid. Not enough remaining space", index); + return 0; + } + entryOffset = static_cast(entryOffset + 34); break; } } @@ -179,7 +187,7 @@ uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attribut { case 0x0001: // fabrics list // Struct _FabricDescriptor - entryLength = 18; + entryLength = 52; break; } break; diff --git a/examples/tv-app/tv-common/gen/attribute-size.cpp b/examples/tv-app/tv-common/gen/attribute-size.cpp index 9052de374a3399..3fcd36e24a50d1 100644 --- a/examples/tv-app/tv-common/gen/attribute-size.cpp +++ b/examples/tv-app/tv-common/gen/attribute-size.cpp @@ -324,7 +324,7 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo { case 0x0001: // fabrics list { - entryLength = 18; + entryLength = 52; if (((index - 1) * entryLength) > (am->size - entryLength)) { ChipLogError(Zcl, "Index %l is invalid.", index); @@ -338,7 +338,15 @@ uint16_t emberAfCopyList(ClusterId clusterId, EmberAfAttributeMetadata * am, boo copyListMember(write ? dest : (uint8_t *) &entry->VendorId, write ? (uint8_t *) &entry->VendorId : src, write, &entryOffset, sizeof(entry->VendorId)); // INT16U copyListMember(write ? dest : (uint8_t *) &entry->NodeId, write ? (uint8_t *) &entry->NodeId : src, write, &entryOffset, - sizeof(entry->NodeId)); // NODE_ID + sizeof(entry->NodeId)); // NODE_ID + chip::ByteSpan * LabelSpan = &entry->Label; // OCTET_STRING + if (CHIP_NO_ERROR != + (write ? WriteByteSpan(dest + entryOffset, 34, LabelSpan) : ReadByteSpan(src + entryOffset, 34, LabelSpan))) + { + ChipLogError(Zcl, "Index %l is invalid. Not enough remaining space", index); + return 0; + } + entryOffset = static_cast(entryOffset + 34); break; } } @@ -674,7 +682,7 @@ uint16_t emberAfAttributeValueListSize(ClusterId clusterId, AttributeId attribut { case 0x0001: // fabrics list // Struct _FabricDescriptor - entryLength = 18; + entryLength = 52; break; } break; diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index c3f88d5793ce75..f9fea01b089b33 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -29,8 +29,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -77,7 +79,7 @@ EmberAfStatus writeFabricAttribute(uint8_t * buffer, int32_t index = -1) index + 1); } -EmberAfStatus writeFabric(FabricId fabricId, NodeId nodeId, uint16_t vendorId, int32_t index) +EmberAfStatus writeFabric(FabricId fabricId, NodeId nodeId, uint16_t vendorId, const uint8_t * fabricLabel, int32_t index) { EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; @@ -85,6 +87,11 @@ EmberAfStatus writeFabric(FabricId fabricId, NodeId nodeId, uint16_t vendorId, i fabricDescriptor.FabricId = fabricId; fabricDescriptor.NodeId = nodeId; fabricDescriptor.VendorId = vendorId; + if (fabricLabel != nullptr) + { + size_t lengthToStore = strnlen(Uint8::to_const_char(fabricLabel), kFabricLabelMaxLengthInBytes); + fabricDescriptor.Label = ByteSpan(fabricLabel, lengthToStore); + } emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Writing admin into attribute store at index %d: fabricId 0x" ChipLogFormatX64 @@ -103,9 +110,10 @@ CHIP_ERROR writeAdminsIntoFabricsListAttribute() uint32_t fabricIndex = 0; for (auto & pairing : GetGlobalAdminPairingTable()) { - NodeId nodeId = pairing.GetNodeId(); - uint64_t fabricId = pairing.GetFabricId(); - uint16_t vendorId = pairing.GetVendorId(); + NodeId nodeId = pairing.GetNodeId(); + uint64_t fabricId = pairing.GetFabricId(); + uint16_t vendorId = pairing.GetVendorId(); + const uint8_t * fabricLabel = pairing.GetFabricLabel(); // Skip over uninitialized admins if (nodeId == kUndefinedNodeId || fabricId == kUndefinedFabricId || vendorId == kUndefinedVendorId) @@ -116,7 +124,7 @@ CHIP_ERROR writeAdminsIntoFabricsListAttribute() ChipLogValueX64(fabricId), ChipLogValueX64(nodeId), vendorId); continue; } - else if (writeFabric(fabricId, nodeId, vendorId, fabricIndex) != EMBER_ZCL_STATUS_SUCCESS) + else if (writeFabric(fabricId, nodeId, vendorId, fabricLabel, fabricIndex) != EMBER_ZCL_STATUS_SUCCESS) { emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Failed to write admin with fabricId 0x" ChipLogFormatX64 " in fabrics list", @@ -292,7 +300,23 @@ bool emberAfOperationalCredentialsClusterUpdateFabricLabelCallback(chip::app::Co { emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: UpdateFabricLabel"); - EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE; + EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; + CHIP_ERROR err; + + // Fetch current fabric + AdminPairingInfo * admin = retrieveCurrentAdmin(); + VerifyOrExit(admin != nullptr, status = EMBER_ZCL_STATUS_FAILURE); + + // Set Label on fabric + err = admin->SetFabricLabel(Label); + VerifyOrExit(err == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); + + // Persist updated fabric + err = GetGlobalAdminPairingTable().Store(admin->GetAdminId()); + VerifyOrExit(err == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE); + +exit: + writeAdminsIntoFabricsListAttribute(); emberAfSendImmediateDefaultResponse(status); return true; } diff --git a/src/app/common/gen/af-structs.h b/src/app/common/gen/af-structs.h index e25afe9c37a96d..720e48666cdfbc 100644 --- a/src/app/common/gen/af-structs.h +++ b/src/app/common/gen/af-structs.h @@ -219,6 +219,7 @@ typedef struct _FabricDescriptor chip::FabricId FabricId; uint16_t VendorId; chip::NodeId NodeId; + chip::ByteSpan Label; } EmberAfFabricDescriptor; // Struct for GpPairingConfigurationGroupList diff --git a/src/app/zap-templates/zcl/custom-types.xml b/src/app/zap-templates/zcl/custom-types.xml index 70ccce8b97c672..5f8fdd48c3a8e1 100644 --- a/src/app/zap-templates/zcl/custom-types.xml +++ b/src/app/zap-templates/zcl/custom-types.xml @@ -58,7 +58,7 @@ limitations under the License. // Change INT16U to new type VendorID #2395 - // TODO: Add Label once CHAR_STRING or OCTET_STRING works + // TODO: Add Label once CHAR_STRING or OCTET_STRING works diff --git a/src/controller/data_model/gen/CHIPClientCallbacks.cpp b/src/controller/data_model/gen/CHIPClientCallbacks.cpp index f585fd84cfc44c..e069f10b87a362 100644 --- a/src/controller/data_model/gen/CHIPClientCallbacks.cpp +++ b/src/controller/data_model/gen/CHIPClientCallbacks.cpp @@ -730,6 +730,9 @@ bool emberAfReadAttributesResponseCallback(ClusterId clusterId, uint8_t * messag CHECK_MESSAGE_LENGTH(8); data[i].NodeId = emberAfGetInt64u(message, 0, 8); message += 8; + CHECK_STATUS(ReadByteSpan(message, 34, &data[i].Label)); + messageLen -= 34; + message += 34; } Callback::Callback * cb = diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m index aa3deaf6fdffde..c6f22369660842 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m @@ -244,6 +244,7 @@ - (void)fetchFabricsList - (IBAction)removeAllFabricsButtonPressed:(id)sender { NSLog(@"Request to Remove All Fabrics."); + [self.removeFabricTextField resignFirstResponder]; UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Remove All Fabrics?" message:@"Are you sure you want to remove all fabrics, this will remove all fabrics on " @@ -280,6 +281,7 @@ - (IBAction)updateFabricLabelButtonPressed:(id)sender { NSString * label = _updateFabricLabelTextField.text; NSLog(@"Request to updateFabricLabel %@", label); + [self.updateFabricLabelTextField resignFirstResponder]; [self updateResult:[NSString stringWithFormat:@"updateFabricLabel command sent."] isError:NO]; [self.cluster updateFabricLabel:label @@ -287,18 +289,20 @@ - (IBAction)updateFabricLabelButtonPressed:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"Got back error trying to updateFabricLabel %@", error); - self->_updateFabricLabelTextField.text = @""; dispatch_async(dispatch_get_main_queue(), ^{ + self->_updateFabricLabelTextField.text = @""; [self updateResult:[NSString stringWithFormat:@"Command updateFabricLabel failed with error %@", error] isError:YES]; }); } else { NSLog(@"Successfully updated the label: %@", values); dispatch_async(dispatch_get_main_queue(), ^{ + self->_updateFabricLabelTextField.text = @""; [self updateResult:[NSString stringWithFormat:@"Command updateFabricLabel succeeded to update label to %@", label] isError:NO]; + [self fetchFabricsList]; }); } }); diff --git a/src/darwin/Framework/CHIP/gen/CHIPClustersObjc.mm b/src/darwin/Framework/CHIP/gen/CHIPClustersObjc.mm index e0e2df748ef1ed..160f92db100c72 100644 --- a/src/darwin/Framework/CHIP/gen/CHIPClustersObjc.mm +++ b/src/darwin/Framework/CHIP/gen/CHIPClustersObjc.mm @@ -3096,7 +3096,9 @@ static void CallbackFn(void * context, uint16_t count, _FabricDescriptor * entri for (uint16_t i = 0; i < count; i++) { values[i] = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:entries[i].FabricId], @"FabricId", [NSNumber numberWithUnsignedShort:entries[i].VendorId], @"VendorId", - [NSNumber numberWithUnsignedLongLong:entries[i].NodeId], @"NodeId", nil]; + [NSNumber numberWithUnsignedLongLong:entries[i].NodeId], @"NodeId", + [NSData dataWithBytes:entries[i].Label.data() length:entries[i].Label.size()], + @"Label", nil]; } id array = [NSArray arrayWithObjects:values count:count]; diff --git a/src/transport/AdminPairingTable.cpp b/src/transport/AdminPairingTable.cpp index 316ab0507f248c..dfe161e021a587 100644 --- a/src/transport/AdminPairingTable.cpp +++ b/src/transport/AdminPairingTable.cpp @@ -30,6 +30,16 @@ using namespace Crypto; namespace Transport { +CHIP_ERROR AdminPairingInfo::SetFabricLabel(const uint8_t * fabricLabel) +{ + const char * charFabricLabel = Uint8::to_const_char(fabricLabel); + size_t stringLength = strnlen(charFabricLabel, kFabricLabelMaxLengthInBytes); + memcpy(mFabricLabel, charFabricLabel, stringLength); + mFabricLabel[stringLength] = '\0'; // Set null terminator + + return CHIP_NO_ERROR; +} + CHIP_ERROR AdminPairingInfo::StoreIntoKVS(PersistentStorageDelegate * kvs) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -45,6 +55,10 @@ CHIP_ERROR AdminPairingInfo::StoreIntoKVS(PersistentStorageDelegate * kvs) info->mFabricId = Encoding::LittleEndian::HostSwap64(mFabricId); info->mVendorId = Encoding::LittleEndian::HostSwap16(mVendorId); + size_t stringLength = strnlen(mFabricLabel, kFabricLabelMaxLengthInBytes); + memcpy(info->mFabricLabel, mFabricLabel, stringLength); + info->mFabricLabel[stringLength] = '\0'; // Set null terminator + if (mOperationalKey != nullptr) { SuccessOrExit(err = mOperationalKey->Serialize(info->mOperationalKey)); @@ -103,6 +117,7 @@ CHIP_ERROR AdminPairingInfo::FetchFromKVS(PersistentStorageDelegate * kvs) AdminId id; uint16_t rootCertLen, opCertLen; + size_t stringLength; SuccessOrExit(err = kvs->SyncGetKeyValue(key, info, infoSize)); @@ -113,6 +128,10 @@ CHIP_ERROR AdminPairingInfo::FetchFromKVS(PersistentStorageDelegate * kvs) rootCertLen = Encoding::LittleEndian::HostSwap16(info->mRootCertLen); opCertLen = Encoding::LittleEndian::HostSwap16(info->mOpCertLen); + stringLength = strnlen(info->mFabricLabel, kFabricLabelMaxLengthInBytes); + memcpy(mFabricLabel, info->mFabricLabel, stringLength); + mFabricLabel[stringLength] = '\0'; // Set null terminator + VerifyOrExit(mAdmin == id, err = CHIP_ERROR_INCORRECT_STATE); if (mOperationalKey == nullptr) diff --git a/src/transport/AdminPairingTable.h b/src/transport/AdminPairingTable.h index 81a371e5ebfda3..45079ef948e96b 100644 --- a/src/transport/AdminPairingTable.h +++ b/src/transport/AdminPairingTable.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,8 @@ namespace chip { namespace Transport { typedef uint16_t AdminId; -static constexpr AdminId kUndefinedAdminId = UINT16_MAX; +static constexpr AdminId kUndefinedAdminId = UINT16_MAX; +static constexpr uint8_t kFabricLabelMaxLengthInBytes = 32; // KVS store is sensitive to length of key strings, based on the underlying // platform. Keeping them short. @@ -66,6 +68,12 @@ class DLL_EXPORT AdminPairingInfo public: AdminPairingInfo() { Reset(); } + // Returns a pointer to a null terminated char array + const uint8_t * GetFabricLabel() const { return Uint8::from_const_char(mFabricLabel); }; + + // Expects a pointer to a null terminated char array + CHIP_ERROR SetFabricLabel(const uint8_t * fabricLabel); + ~AdminPairingInfo() { if (mOperationalKey != nullptr) @@ -129,10 +137,11 @@ class DLL_EXPORT AdminPairingInfo */ void Reset() { - mNodeId = kUndefinedNodeId; - mAdmin = kUndefinedAdminId; - mFabricId = kUndefinedFabricId; - mVendorId = kUndefinedVendorId; + mNodeId = kUndefinedNodeId; + mAdmin = kUndefinedAdminId; + mFabricId = kUndefinedFabricId; + mVendorId = kUndefinedVendorId; + mFabricLabel[0] = '\0'; if (mOperationalKey != nullptr) { @@ -145,10 +154,11 @@ class DLL_EXPORT AdminPairingInfo friend class AdminPairingTable; private: - NodeId mNodeId = kUndefinedNodeId; - FabricId mFabricId = kUndefinedFabricId; - AdminId mAdmin = kUndefinedAdminId; - uint16_t mVendorId = kUndefinedVendorId; + NodeId mNodeId = kUndefinedNodeId; + FabricId mFabricId = kUndefinedFabricId; + AdminId mAdmin = kUndefinedAdminId; + uint16_t mVendorId = kUndefinedVendorId; + char mFabricLabel[kFabricLabelMaxLengthInBytes + 1] = { '\0' }; AccessControlList mACL; @@ -179,6 +189,8 @@ class DLL_EXPORT AdminPairingInfo uint64_t mFabricId; /* This field is serialized in LittleEndian byte order */ uint16_t mVendorId; /* This field is serialized in LittleEndian byte order */ + char mFabricLabel[kFabricLabelMaxLengthInBytes + 1] = { '\0' }; + uint16_t mRootCertLen; /* This field is serialized in LittleEndian byte order */ uint16_t mOpCertLen; /* This field is serialized in LittleEndian byte order */