blob: 94b315b7e37c58008ec8f3f0e14e19a704571449 [file] [log] [blame]
/*
*
* 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.
*/
#pragma once
#include <app/ConcreteAttributePath.h>
#include <app/util/basic-types.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
#include <lib/core/GroupId.h>
#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <string.h>
namespace chip {
/**
* This is the common key allocation policy for all classes using
* PersistentStorageDelegate storage.
*
* Keys should have the following formats:
*
* * Keys that are not tied to a specific fabric: "g/....".
* * Keys that are tied to a specific fabric: "f/%x/...." where the %x gets
* replaced by the fabric index.
*/
class DefaultStorageKeyAllocator
{
public:
DefaultStorageKeyAllocator() = default;
const char * KeyName() { return mKeyName; }
// Fabric Table
const char * FabricIndexInfo() { return SetConst("g/fidx"); }
const char * FabricNOC(FabricIndex fabric) { return Format("f/%x/n", fabric); }
const char * FabricICAC(FabricIndex fabric) { return Format("f/%x/i", fabric); }
const char * FabricRCAC(FabricIndex fabric) { return Format("f/%x/r", fabric); }
const char * FabricMetadata(FabricIndex fabric) { return Format("f/%x/m", fabric); }
const char * FabricOpKey(FabricIndex fabric) { return Format("f/%x/o", fabric); }
// Fail-safe handling
const char * FailSafeCommitMarkerKey() { return SetConst("g/fs/c"); }
const char * FailSafeNetworkConfig() { return SetConst("g/fs/n"); }
// LastKnownGoodTime
const char * LastKnownGoodTimeKey() { return SetConst("g/lkgt"); }
// Session resumption
const char * FabricSession(FabricIndex fabric, NodeId nodeId)
{
return Format("f/%x/s/%08" PRIX32 "%08" PRIX32, fabric, static_cast<uint32_t>(nodeId >> 32), static_cast<uint32_t>(nodeId));
}
const char * SessionResumptionIndex() { return SetConst("g/sri"); }
const char * SessionResumption(const char * resumptionIdBase64) { return Format("g/s/%s", resumptionIdBase64); }
// Access Control
const char * AccessControlAclEntry(FabricIndex fabric, size_t index)
{
return Format("f/%x/ac/0/%x", fabric, static_cast<unsigned>(index));
}
const char * AccessControlExtensionEntry(FabricIndex fabric) { return Format("f/%x/ac/1", fabric); }
// Group Message Counters
const char * GroupDataCounter() { return SetConst("g/gdc"); }
const char * GroupControlCounter() { return SetConst("g/gcc"); }
// Device Information Provider
const char * UserLabelLengthKey(EndpointId endpoint) { return Format("g/userlbl/%x", endpoint); }
const char * UserLabelIndexKey(EndpointId endpoint, uint32_t index) { return Format("g/userlbl/%x/%" PRIx32, endpoint, index); }
// Group Data Provider
// List of fabric indices that have endpoint-to-group associations defined.
const char * GroupFabricList() { return SetConst("g/gfl"); }
const char * FabricGroups(chip::FabricIndex fabric) { return Format("f/%x/g", fabric); }
const char * FabricGroup(chip::FabricIndex fabric, chip::GroupId group) { return Format("f/%x/g/%x", fabric, group); }
const char * FabricGroupKey(chip::FabricIndex fabric, uint16_t index) { return Format("f/%x/gk/%x", fabric, index); }
const char * FabricGroupEndpoint(chip::FabricIndex fabric, chip::GroupId group, chip::EndpointId endpoint)
{
return Format("f/%x/g/%x/e/%x", fabric, group, endpoint);
}
const char * FabricKeyset(chip::FabricIndex fabric, uint16_t keyset) { return Format("f/%x/k/%x", fabric, keyset); }
const char * AttributeValue(const app::ConcreteAttributePath & aPath)
{
// Needs at most 26 chars: 6 for "g/a///", 4 for the endpoint id, 8 each
// for the cluster and attribute ids.
return Format("g/a/%x/%" PRIx32 "/%" PRIx32, aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId);
}
// TODO: Should store fabric-specific parts of the binding list under keys
// starting with "f/%x/".
const char * BindingTable() { return SetConst("g/bt"); }
const char * BindingTableEntry(uint8_t index) { return Format("g/bt/%x", index); }
const char * OTADefaultProviders() { return SetConst("g/o/dp"); }
const char * OTACurrentProvider() { return SetConst("g/o/cp"); }
const char * OTAUpdateToken() { return SetConst("g/o/ut"); }
const char * OTACurrentUpdateState() { return SetConst("g/o/us"); }
const char * OTATargetVersion() { return SetConst("g/o/tv"); }
// Event number counter.
const char * IMEventNumber() { return SetConst("g/im/ec"); }
protected:
// The ENFORCE_FORMAT args are "off by one" because this is a class method,
// with an implicit "this" as first arg.
const char * ENFORCE_FORMAT(2, 3) Format(const char * format, ...)
{
va_list args;
va_start(args, format);
vsnprintf(mKeyNameBuffer, sizeof(mKeyNameBuffer), format, args);
va_end(args);
return mKeyName = mKeyNameBuffer;
}
const char * SetConst(const char * keyName) { return mKeyName = keyName; }
private:
const char * mKeyName = nullptr;
char mKeyNameBuffer[PersistentStorageDelegate::kKeyLengthMax + 1] = { 0 };
};
} // namespace chip