From 19e6559b21cb9ec8183a2c030e86cb8a2e97fa17 Mon Sep 17 00:00:00 2001 From: shana-apple <61782012+shana-apple@users.noreply.github.com> Date: Wed, 2 Jun 2021 18:16:39 +0200 Subject: [PATCH] Add Label to FabricDescriptorStruct and hook up logic with UpdateFabricLabel (#6670) * Adds Label to FabricDescriptor struct + regens files Adds fabric label to AdminPairingInfo with persistence support Hooks up UpdateFabricLabel to SetFabricLabel and writes the fabric label into the attribute list upon changes. How was this tested? (at least one bullet point required) - Added UI in chiptool ios to test this and tested that the label can be modifiled, nulled out and persists after m5stack reboots * regen files * Restyled by whitespace * Restyled by clang-format * switching to -std=gnu++14 * Restyled by clang-format * switch from 14 to 17 Co-authored-by: Restyled.io --- config/nrfconnect/app/enable-gnu-std.cmake | 3 ++ .../gen/attribute-size.cpp | 14 ++++++-- .../chip-tool/commands/clusters/Commands.h | 1 + .../lighting-common/gen/attribute-size.cpp | 14 ++++++-- .../lighting-app/nrfconnect/CMakeLists.txt | 2 ++ .../lock-common/gen/attribute-size.cpp | 14 ++++++-- examples/lock-app/nrfconnect/CMakeLists.txt | 2 ++ .../pigweed-app/nrfconnect/CMakeLists.txt | 2 ++ examples/pump-app/nrfconnect/CMakeLists.txt | 2 ++ .../pump-common/gen/attribute-size.cpp | 14 ++++++-- .../nrfconnect/CMakeLists.txt | 2 ++ .../gen/attribute-size.cpp | 14 ++++++-- examples/shell/nrfconnect/CMakeLists.txt | 2 ++ .../esp32/main/gen/attribute-size.cpp | 14 ++++++-- .../tv-app/tv-common/gen/attribute-size.cpp | 14 ++++++-- .../operational-credentials-server.cpp | 36 +++++++++++++++---- src/app/common/gen/af-structs.h | 1 + src/app/zap-templates/zcl/custom-types.xml | 2 +- .../data_model/gen/CHIPClientCallbacks.cpp | 3 ++ .../Fabric/FabricUIViewController.m | 6 +++- .../Framework/CHIP/gen/CHIPClustersObjc.mm | 4 ++- src/transport/AdminPairingTable.cpp | 19 ++++++++++ src/transport/AdminPairingTable.h | 30 +++++++++++----- 23 files changed, 176 insertions(+), 39 deletions(-) create mode 100644 config/nrfconnect/app/enable-gnu-std.cmake 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 */