Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/platform/silabs/MatterConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,6 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName)
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
#endif // SL_WIFI

ReturnErrorOnFailure(PlatformMgr().InitChipStack());

chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(appName);

// Provision Manager
Expand All @@ -279,6 +277,8 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName)
SetCommissionableDataProvider(&provision.GetStorage());
ChipLogProgress(DeviceLayer, "Provision mode %s", provision.IsProvisionRequired() ? "ENABLED" : "disabled");

ReturnErrorOnFailure(PlatformMgr().InitChipStack());

#if CHIP_ENABLE_OPENTHREAD
ReturnErrorOnFailure(InitOpenThread());
#endif
Expand Down
278 changes: 205 additions & 73 deletions examples/platform/silabs/provision/ProvisionStorageDefault.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,12 @@ CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan)
return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR Storage::MigrateAttestationCredentialAPI()
{
// Not implemented for the ProvisionStorageFlash.
return CHIP_NO_ERROR;
}

} // namespace Provision
} // namespace Silabs
} // namespace DeviceLayer
Expand Down
12 changes: 12 additions & 0 deletions src/platform/silabs/MigrationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/

#include "MigrationManager.h"
#include <headers/ProvisionManager.h>
#include <headers/ProvisionStorage.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/silabs/SilabsConfig.h>
#include <stdio.h>
Expand All @@ -41,6 +43,7 @@ static migrationData_t migrationTable[] = {
{ .migrationGroup = 2, .migrationFunc = MigrateDacProvider },
{ .migrationGroup = 3, .migrationFunc = MigrateCounterConfigs },
{ .migrationGroup = 4, .migrationFunc = MigrateHardwareVersion },
{ .migrationGroup = 5, .migrationFunc = MigrateCTM },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning !!!
I think this migration group is in use in CSA for doorlock credentials.
We need to CP the migration PR before adding this migration.

There is also a catch22 here. Once this is merged, all apps must use CTM by default, else Migration will be done when CTM is not in use and will never be called again.

IF CTM implementation can become default, then we shouldn't keep SilabsConfig and SilabsConfigCTM. Does the Mig also work for 917?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are keeping it since Series 2 cannot move to CTM right now because in series 2 the token interface relies on zigbee or embernet.

Regarding 917, I do not think the CTM supports it but I have to confirm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the catch 22, the nvm location will be the same for all, however since Series2 cannot use the CTM API currently, we need to keep the SilabsConfig.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final version of the DoorLock migration do not use the MigrationManager. It required to move the migrations later on on the initialization, which I deemed too risky, so the DoorLock migration end up being a standalone process.

// add any additional migration neccesary. migrationGroup should stay equal if done in the same commit or increment by 1 for
// each new entry.
};
Expand Down Expand Up @@ -132,6 +135,15 @@ void MigrateHardwareVersion(void)
MigrationManager::MigrateUint16(kOldKey_HardwareVersion, SilabsConfig::kConfigKey_HardwareVersion);
}

void MigrateCTM(void)
{
CHIP_ERROR err = Provision::Manager::GetInstance().GetStorage().MigrateAttestationCredentialAPI();
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "Failed to migrate CTM: %s", ErrorStr(err));
}
}

} // namespace Silabs
} // namespace DeviceLayer
} // namespace chip
1 change: 1 addition & 0 deletions src/platform/silabs/MigrationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ void MigrateKvsMap(void);
void MigrateDacProvider(void);
void MigrateCounterConfigs(void);
void MigrateHardwareVersion(void);
void MigrateCTM(void);

} // namespace Silabs
} // namespace DeviceLayer
Expand Down
2 changes: 2 additions & 0 deletions src/platform/silabs/SiWx917/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ static_library("SiWx917") {
"${silabs_platform_dir}/PlatformManagerImpl.h",
"${silabs_platform_dir}/SilabsConfig.cpp",
"${silabs_platform_dir}/SilabsConfig.h",
"${silabs_platform_dir}/SilabsConfigUtils.cpp",
"${silabs_platform_dir}/SilabsConfigUtils.h",
"${silabs_platform_dir}/SystemPlatformConfig.h",
"../../FreeRTOS/SystemTimeSupport.cpp",
"../../SingletonConfigurationManager.cpp",
Expand Down
20 changes: 1 addition & 19 deletions src/platform/silabs/SilabsConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <lib/support/CodeUtils.h>
#include <platform/internal/testing/ConfigUnitTest.h>
#include <platform/silabs/CHIPDevicePlatformConfig.h>
#include <platform/silabs/SilabsConfigUtils.h>

#include <nvm3.h>
#include <nvm3_default.h>
Expand Down Expand Up @@ -63,25 +64,6 @@ namespace DeviceLayer {
namespace Internal {

namespace {
CHIP_ERROR MapNvm3Error(sl_status_t nvm3Res)
{
CHIP_ERROR err;

switch (nvm3Res)
{
case SL_STATUS_OK:
err = CHIP_NO_ERROR;
break;
case SL_STATUS_NOT_FOUND:
err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
break;
default:
err = CHIP_ERROR(ChipError::Range::kPlatform, (nvm3Res & 0xFF) + CHIP_DEVICE_CONFIG_SILABS_NVM3_ERROR_MIN);
break;
}

return err;
}

template <typename T>
CHIP_ERROR ReadConfigValueHelper(SilabsConfig::Key key, T & val)
Expand Down
66 changes: 34 additions & 32 deletions src/platform/silabs/SilabsConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
#include <functional>
#include <platform/CHIPDeviceError.h>

#ifndef SL_COMMON_TOKEN_MANAGER_ENABLE_DYNAMIC_TOKENS
#ifdef SL_TOKEN_MANAGER_DEFINES_H
#include <sl_token_manager_defines.h>
#else
#include "nvm3.h"
#include "nvm3_hal_flash.h"
#else
#include <sl_token_manager_defines.h>
#endif

#ifndef KVS_MAX_ENTRIES
Expand Down Expand Up @@ -61,7 +61,20 @@ namespace Internal {
* the template class (e.g. the ReadConfigValue() method).
*/

#ifndef SL_COMMON_TOKEN_MANAGER_ENABLE_DYNAMIC_TOKENS
#ifdef SL_TOKEN_MANAGER_DEFINES_H
inline constexpr uint32_t kUserNvm3KeyDomainLoLimit = SL_TOKEN_NVM3_REGION_USER;
inline constexpr uint32_t kUserNvm3KeyDomainHiLimit = SL_TOKEN_NVM3_REGION_ZIGBEE - 1;

// Only keep the MSBs of the Matter Region. The LSB of the region is determined by the keyBaseOffset.
// with SilabsConfigKey Helper function.
inline constexpr uint32_t kMatterNvm3KeyDomain = (SL_TOKEN_NVM3_REGION_MATTER & 0xFFFF000);

constexpr inline uint32_t SilabsConfigKey(uint8_t keyBaseOffset, uint8_t id)
{
return SL_TOKEN_TYPE_NVM3 | kMatterNvm3KeyDomain | static_cast<uint32_t>(keyBaseOffset) << 8 | id;
}

#else
// Silabs NVM3 objects use a 20-bit number,
// NVM3 Key 19:16 Stack region
// NVM3 Key 15:0 Available NVM3 keys 0x0000 -> 0xFFFF.
Expand All @@ -77,24 +90,6 @@ constexpr inline uint32_t SilabsConfigKey(uint8_t keyBaseOffset, uint8_t id)
{
return kMatterNvm3KeyDomain | static_cast<uint32_t>(keyBaseOffset) << 8 | id;
}
#else

inline constexpr uint32_t kUserNvm3KeyDomainLoLimit = SL_TOKEN_NVM3_REGION_USER;
inline constexpr uint32_t kUserNvm3KeyDomainHiLimit = SL_TOKEN_NVM3_REGION_ZIGBEE - 1;

// Only keep the MSBs of the Matter Region. The LSB of the region is determined by the keyBaseOffset.
// with SilabsConfigKey Helper function.
inline constexpr uint32_t kMatterNvm3KeyDomain = (SL_TOKEN_NVM3_REGION_MATTER & 0xFFFF000);

constexpr inline uint32_t SilabsConfigKey(uint8_t keyBaseOffset, uint8_t id)
{
return SL_TOKEN_TYPE_NVM3 | kMatterNvm3KeyDomain | static_cast<uint32_t>(keyBaseOffset) << 8 | id;
}

constexpr inline uint32_t SilabsSecureTokenKey(uint8_t keyBaseOffset, uint8_t id)
{
return SL_TOKEN_TYPE_STATIC_SECURE | static_cast<uint32_t>(keyBaseOffset) << 8 | id;
}
Comment on lines -94 to -97
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the story with this SL_TOKEN_TYPE_STATIC_SECURE and now removal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were going to use NVM3, then we weren't, now we are going to use it again.

#endif

inline constexpr uint32_t kMatterNvm3KeyLoLimit = 0x087200U; // Do not modify without Silabs GSDK team approval
Expand Down Expand Up @@ -151,16 +146,23 @@ class SilabsConfig
// SHALL NOT be the same as the UniqueID attribute exposed in the Basic Information cluster.
static constexpr Key kConfigKey_PersistentUniqueId = SilabsConfigKey(kMatterFactory_KeyBase, 0x1F);
static constexpr Key kConfigKey_Creds_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x20);
static constexpr Key kConfigKey_Creds_Base_Addr = SilabsConfigKey(kMatterFactory_KeyBase, 0x21);
static constexpr Key kConfigKey_Creds_DAC_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x22);
static constexpr Key kConfigKey_Creds_DAC_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x23);
static constexpr Key kConfigKey_Creds_PAI_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x24);
static constexpr Key kConfigKey_Creds_PAI_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x25);
static constexpr Key kConfigKey_Creds_CD_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x26);
static constexpr Key kConfigKey_Creds_CD_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x27);
static constexpr Key kConfigKey_Provision_Request = SilabsConfigKey(kMatterFactory_KeyBase, 0x28);
static constexpr Key kConfigKey_Provision_Version = SilabsConfigKey(kMatterFactory_KeyBase, 0x29);
static constexpr Key kOtaTlvEncryption_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x30);

// DEPRECATED KEYS : BEGIN
static constexpr Key kConfigKey_Creds_Base_Addr = SilabsConfigKey(kMatterFactory_KeyBase, 0x21);
static constexpr Key kConfigKey_Creds_DAC_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x22);
static constexpr Key kConfigKey_Creds_PAI_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x24);
static constexpr Key kConfigKey_Creds_CD_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x26);
// DEPRECATED KEYS : END

static constexpr Key kConfigKey_Creds_DAC_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x23);
static constexpr Key kConfigKey_Creds_PAI_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x25);
static constexpr Key kConfigKey_Creds_CD_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x27);
static constexpr Key kConfigKey_Provision_Request = SilabsConfigKey(kMatterFactory_KeyBase, 0x28);
static constexpr Key kConfigKey_Provision_Version = SilabsConfigKey(kMatterFactory_KeyBase, 0x29);
static constexpr Key kOtaTlvEncryption_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x30);
static constexpr Key kConfigKey_Creds_Dac = SilabsConfigKey(kMatterFactory_KeyBase, 0x31);
static constexpr Key kConfigKey_Creds_Pai = SilabsConfigKey(kMatterFactory_KeyBase, 0x32);
static constexpr Key kConfigKey_Creds_CD = SilabsConfigKey(kMatterFactory_KeyBase, 0x33);
Comment on lines +163 to +165
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need follow-up/aggrement on where to store does. I don't think nvm3 is the way to go.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NVM3 would have been the easy way to get series 2 on board as well.


// Matter Config Keys
static constexpr Key kConfigKey_ServiceConfig = SilabsConfigKey(kMatterConfig_KeyBase, 0x01);
Expand Down
44 changes: 8 additions & 36 deletions src/platform/silabs/SilabsConfigCTM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <lib/support/CodeUtils.h>
#include <platform/internal/testing/ConfigUnitTest.h>
#include <platform/silabs/CHIPDevicePlatformConfig.h>
#include <platform/silabs/SilabsConfigUtils.h>

#include "uart.h"
#include <FreeRTOS.h>
Expand All @@ -35,7 +36,7 @@
#include <nvm3_hal_flash.h>
#include <nvm3_lock.h>
#include <semphr.h>
#include <sl_token_manager_interface.h>
#include <sl_token_manager_api.h>
// Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd
// for an application controlled re-entrance protection
static SemaphoreHandle_t nvm3_Sem;
Expand Down Expand Up @@ -63,25 +64,6 @@ namespace chip {
namespace DeviceLayer {
namespace Internal {
namespace {
CHIP_ERROR MapNvm3Error(sl_status_t nvm3Res)
{
CHIP_ERROR err;

switch (nvm3Res)
{
case SL_STATUS_OK:
err = CHIP_NO_ERROR;
break;
case SL_STATUS_NOT_FOUND:
err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
break;
default:
err = CHIP_ERROR(ChipError::Range::kPlatform, (nvm3Res & 0xFF) + CHIP_DEVICE_CONFIG_SILABS_NVM3_ERROR_MIN);
break;
}

return err;
}

template <typename T>
CHIP_ERROR ReadConfigValueHelper(SilabsConfig::Key key, T & val)
Expand All @@ -98,9 +80,7 @@ CHIP_ERROR ReadConfigValueHelper(SilabsConfig::Key key, T & val)
// Ensure the data size matches the expected size
VerifyOrReturnError(dataLen == sizeof(T), CHIP_ERROR_INVALID_ARGUMENT);

// TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated
uint32_t unusedSizeOut;
ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, dataLen, &unusedSizeOut)));
ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, dataLen)));

val = tmpVal;
return CHIP_NO_ERROR;
Expand Down Expand Up @@ -177,9 +157,7 @@ CHIP_ERROR SilabsConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize,
// terminator char).
VerifyOrExit((bufSize > dataLen), err = CHIP_ERROR_BUFFER_TOO_SMALL);

// TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated
uint32_t unusedSizeOut;
err = MapNvm3Error(sl_token_manager_get_data(key, buf, dataLen, &unusedSizeOut));
err = MapNvm3Error(sl_token_manager_get_data(key, buf, dataLen));
SuccessOrExit(err);

outLen = ((dataLen == 1) && (buf[0] == 0)) ? 0 : dataLen;
Expand All @@ -195,9 +173,7 @@ CHIP_ERROR SilabsConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize,
{
// Read the first byte of the nvm3 string into a tmp var.
char firstByte;
// TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated
uint32_t unusedSizeOut;
err = MapNvm3Error(sl_token_manager_get_data(key, &firstByte, 1, &unusedSizeOut));
err = MapNvm3Error(sl_token_manager_get_data(key, &firstByte, 1));
SuccessOrExit(err);

outLen = (firstByte == 0) ? 0 : dataLen;
Expand Down Expand Up @@ -225,14 +201,12 @@ CHIP_ERROR SilabsConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSi
size_t maxReadLength = dataLen - offset;
if (bufSize >= maxReadLength)
{
// TODO: No API currently exist for partial reads in sl_token_manager_interface, replace this when available
ReturnErrorOnFailure(MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, maxReadLength)));
ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_partial_data(key, buf, offset, maxReadLength)));
outLen = maxReadLength;
}
else
{
// TODO: No API currently exist for partial reads in sl_token_manager_interface, replace this when available
ReturnErrorOnFailure(MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, bufSize)));
ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_partial_data(key, buf, offset, bufSize)));
// read was successful, but we did not read all the data from the object.
outLen = bufSize;
return CHIP_ERROR_BUFFER_TOO_SMALL;
Expand All @@ -248,9 +222,7 @@ CHIP_ERROR SilabsConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & v

VerifyOrReturnError(ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.

// TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated
uint32_t unusedSizeOut;
ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, sizeof(tmpVal), &unusedSizeOut)));
ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, sizeof(tmpVal))));
val = tmpVal;
return CHIP_NO_ERROR;
}
Expand Down
56 changes: 56 additions & 0 deletions src/platform/silabs/SilabsConfigUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

/**
* @file
* Utility functions for Silicon Labs platform error handling
* and common operations.
*/

#include <platform/silabs/SilabsConfigUtils.h>

#include <lib/core/CHIPError.h>
#include <lib/support/CodeUtils.h>
#include <platform/CHIPDeviceError.h>

namespace chip {
namespace DeviceLayer {
namespace Internal {

CHIP_ERROR MapNvm3Error(sl_status_t nvm3Res)
{
CHIP_ERROR err;

switch (nvm3Res)
{
case SL_STATUS_OK:
err = CHIP_NO_ERROR;
break;
case SL_STATUS_NOT_FOUND:
err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
break;
default:
err = CHIP_ERROR(ChipError::Range::kPlatform, (nvm3Res & 0xFF) + CHIP_DEVICE_CONFIG_SILABS_NVM3_ERROR_MIN);
break;
}

return err;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Loading
Loading