blob: 819c0299945ed4b8b812d5735734110c13c26063 [file] [log] [blame]
/*
*
* Copyright (c) 2023 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.
*/
#include "CastingStore.h"
#include <lib/core/TLV.h>
#include <platform/KeyValueStoreManager.h>
namespace matter {
namespace casting {
namespace support {
CastingStore * CastingStore::_CastingStore = nullptr;
CastingStore::CastingStore() {}
CastingStore * CastingStore::GetInstance()
{
if (_CastingStore == nullptr)
{
_CastingStore = new CastingStore();
}
return _CastingStore;
}
CHIP_ERROR CastingStore::AddOrUpdate(core::CastingPlayer castingPlayer)
{
ChipLogProgress(AppServer, "CastingStore::AddOrUpdate");
// Read cache of CastingPlayers
std::vector<core::CastingPlayer> castingPlayers = ReadAll();
// search for castingPlayer in CastingStore cache and overwrite it, if found
if (castingPlayers.size() != 0)
{
auto it = std::find_if(
castingPlayers.begin(), castingPlayers.end(),
[castingPlayer](const core::CastingPlayer & castingPlayerParam) { return castingPlayerParam == castingPlayer; });
if (it != castingPlayers.end())
{
unsigned index = (unsigned int) std::distance(castingPlayers.begin(), it);
castingPlayers[index] = castingPlayer;
ChipLogProgress(AppServer, "CastingStore::AddOrUpdate updating CastingPlayer in CastingStore cache");
return WriteAll(castingPlayers); // return early
}
}
// add *new* castingPlayer to CastingStore cache
castingPlayers.push_back(castingPlayer);
ChipLogProgress(AppServer, "CastingStore::AddOrUpdate adding new CastingPlayer in CastingStore cache");
return WriteAll(castingPlayers);
}
std::vector<core::CastingPlayer> CastingStore::ReadAll()
{
ChipLogProgress(AppServer, "CastingStore::ReadAll called");
CHIP_ERROR err = CHIP_NO_ERROR;
std::vector<core::CastingPlayer> castingPlayers;
uint8_t castingStoreData[kCastingStoreDataMaxBytes];
size_t castingStoreDataSize = 0;
err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(kCastingStoreDataKey, castingStoreData,
kCastingStoreDataMaxBytes, &castingStoreDataSize);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "KeyValueStoreMgr.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
ChipLogProgress(AppServer, "CastingStore::ReadAll Read TLV(CastingStoreData) from KVS store with size: %lu bytes",
static_cast<unsigned long>(castingStoreDataSize));
chip::TLV::TLVReader reader;
reader.Init(castingStoreData);
// read the envelope (and version)
err = reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag());
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Next failed %" CHIP_ERROR_FORMAT, err.Format()));
chip::TLV::TLVType outerContainerType;
err = reader.EnterContainer(outerContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
err = reader.Next();
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Next failed %" CHIP_ERROR_FORMAT, err.Format()));
chip::TLV::Tag outerContainerTag = reader.GetTag();
uint8_t outerContainerTagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(outerContainerTag));
VerifyOrReturnValue(outerContainerTagNum == kCastingStoreDataVersionTag, castingPlayers,
ChipLogError(AppServer, "CastingStoreDataVersionTag not found"));
uint32_t version;
err = reader.Get(version);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
ChipLogProgress(AppServer, "CastingStore::ReadAll TLV(CastingStoreData) version: %d", version);
// Entering CastingPlayers container
err = reader.Next();
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Next failed %" CHIP_ERROR_FORMAT, err.Format()));
chip::TLV::TLVType castingPlayersContainerType;
err = reader.EnterContainer(castingPlayersContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
// Entering CastingPlayer container
chip::TLV::TLVType castingPlayerContainerType;
err = reader.EnterContainer(castingPlayerContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
core::CastingPlayerAttributes attributes;
std::vector<core::EndpointAttributes> endpointAttributesList;
std::map<chip::EndpointId, std::vector<chip::ClusterId>> endpointServerListMap;
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
chip::TLV::Tag castingPlayerContainerTag = reader.GetTag();
VerifyOrReturnValue(chip::TLV::IsContextTag(castingPlayerContainerTag), std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "Unexpected non-context TLV tag"));
uint8_t castingPlayerContainerTagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(castingPlayerContainerTag));
if (castingPlayerContainerTagNum == kCastingPlayerIdTag)
{
err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.id), core::kIdMaxLength + 1);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerNodeIdTag)
{
err = reader.Get(attributes.nodeId);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerFabricIndexTag)
{
err = reader.Get(attributes.fabricIndex);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerVendorIdTag)
{
err = reader.Get(attributes.vendorId);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerProductIdTag)
{
err = reader.Get(attributes.productId);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerDeviceTypeIdTag)
{
err = reader.Get(attributes.deviceType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerSupportsCommissionerGeneratedPasscodeTag)
{
err = reader.Get(attributes.supportsCommissionerGeneratedPasscode);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerPortTag)
{
err = reader.Get(attributes.port);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerInstanceNameTag)
{
err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.instanceName),
chip::Dnssd::Commission::kInstanceNameMaxLength + 1);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerDeviceNameTag)
{
err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.deviceName), chip::Dnssd::kMaxDeviceNameLen + 1);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerHostNameTag)
{
err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.hostName), chip::Dnssd::kHostNameMaxLength + 1);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (castingPlayerContainerTagNum == kCastingPlayerEndpointsContainerTag)
{
// Entering Endpoints container
chip::TLV::TLVType endpointsContainerType;
err = reader.EnterContainer(endpointsContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
core::EndpointAttributes endpointAttributes;
std::vector<chip::ClusterId> serverList;
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
// Entering Endpoint container
chip::TLV::TLVType endpointContainerType;
err = reader.EnterContainer(endpointContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
chip::TLV::Tag endpointContainerTag = reader.GetTag();
VerifyOrReturnValue(chip::TLV::IsContextTag(endpointContainerTag), std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "Unexpected non-context TLV tag"));
uint8_t endpointContainerTagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(endpointContainerTag));
if (endpointContainerTagNum == kCastingPlayerEndpointIdTag)
{
err = reader.Get(endpointAttributes.mId);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (endpointContainerTagNum == kCastingPlayerEndpointVendorIdTag)
{
err = reader.Get(endpointAttributes.mVendorId);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (endpointContainerTagNum == kCastingPlayerEndpointProductIdTag)
{
err = reader.Get(endpointAttributes.mProductId);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
std::vector<chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType> deviceTypeList;
if (endpointContainerTagNum == kCastingPlayerEndpointDeviceTypeListContainerTag)
{
// Entering DeviceTypeList container
chip::TLV::TLVType deviceTypeListContainerType;
err = reader.EnterContainer(deviceTypeListContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
// Entering DeviceTypeStruct container
chip::TLV::TLVType deviceTypeStructContainerType;
err = reader.EnterContainer(deviceTypeStructContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType deviceTypeStruct;
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
chip::TLV::Tag deviceTypeStructContainerTag = reader.GetTag();
VerifyOrReturnValue(chip::TLV::IsContextTag(deviceTypeStructContainerTag),
std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "Unexpected non-context TLV tag"));
uint8_t deviceTypeStructContainerTagNum =
static_cast<uint8_t>(chip::TLV::TagNumFromTag(deviceTypeStructContainerTag));
if (deviceTypeStructContainerTagNum == kCastingPlayerEndpointDeviceTypeTag)
{
err = reader.Get(deviceTypeStruct.deviceType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
if (deviceTypeStructContainerTagNum == kCastingPlayerEndpointDeviceTypeRevisionTag)
{
err = reader.Get(deviceTypeStruct.revision);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
}
if (err == CHIP_END_OF_TLV)
{
// Exiting DeviceTypeStruct container
err = reader.ExitContainer(deviceTypeStructContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer,
"TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT,
err.Format()));
deviceTypeList.push_back(deviceTypeStruct);
continue;
}
}
if (err == CHIP_END_OF_TLV)
{
// Exiting DeviceTypeList container
err = reader.ExitContainer(deviceTypeListContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
endpointAttributes.mDeviceTypeList = deviceTypeList;
continue;
}
}
if (endpointContainerTagNum == kCastingPlayerEndpointServerListContainerTag)
{
// Entering ServerList container
chip::TLV::TLVType serverListContainerType;
err = reader.EnterContainer(serverListContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
chip::TLV::Tag serverListContainerTag = reader.GetTag();
VerifyOrReturnValue(chip::TLV::IsContextTag(serverListContainerTag),
std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "Unexpected non-context TLV tag"));
uint8_t serverListContainerTagNum =
static_cast<uint8_t>(chip::TLV::TagNumFromTag(serverListContainerTag));
if (serverListContainerTagNum == kCastingPlayerEndpointServerClusterIdTag)
{
chip::ClusterId clusterId;
err = reader.Get(clusterId);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
serverList.push_back(clusterId);
continue;
}
}
if (err == CHIP_END_OF_TLV)
{
// Exiting ServerList container
err = reader.ExitContainer(serverListContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
}
}
if (err == CHIP_END_OF_TLV)
{
// Exiting Endpoint container
err = reader.ExitContainer(endpointContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
endpointAttributesList.push_back(endpointAttributes);
endpointServerListMap[endpointAttributes.mId] = serverList;
serverList.clear();
continue;
}
}
if (err == CHIP_END_OF_TLV)
{
// Exiting Endpoints container
err = reader.ExitContainer(endpointsContainerType);
VerifyOrReturnValue(
err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
continue;
}
}
}
if (err == CHIP_END_OF_TLV)
{
// Exiting CastingPlayer container
err = reader.ExitContainer(castingPlayerContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
// create a castingPlayer with Endpoints and add it to the castingPlayers to be returned
core::CastingPlayer castingPlayer(attributes);
for (auto & endpointAttributes : endpointAttributesList)
{
std::shared_ptr<core::Endpoint> endpoint(new core::Endpoint(&castingPlayer, endpointAttributes));
endpoint->RegisterClusters(endpointServerListMap[endpointAttributes.mId]);
castingPlayer.RegisterEndpoint(endpoint);
}
castingPlayers.push_back(castingPlayer);
continue;
}
}
VerifyOrReturnValue(err == CHIP_END_OF_TLV, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLV parsing failed %" CHIP_ERROR_FORMAT, err.Format()));
err = reader.ExitContainer(castingPlayersContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
err = reader.ExitContainer(outerContainerType);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
ChipLogProgress(AppServer, "CastingStore::ReadAll CastingPlayers size: %lu", static_cast<unsigned long>(castingPlayers.size()));
return castingPlayers;
}
CHIP_ERROR CastingStore::WriteAll(std::vector<core::CastingPlayer> castingPlayers)
{
ChipLogProgress(AppServer, "CastingStore::WriteAll called");
chip::TLV::TLVWriter tlvWriter;
uint8_t castingStoreData[kCastingStoreDataMaxBytes];
tlvWriter.Init(castingStoreData, kCastingStoreDataMaxBytes);
chip::TLV::TLVType outerContainerType;
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerContainerType));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingStoreDataVersionTag), kCurrentCastingStoreDataVersion));
chip::TLV::TLVType castingPlayersContainerType;
// CastingPlayers container starts
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayersContainerTag), chip::TLV::kTLVType_Array,
castingPlayersContainerType));
for (auto & castingPlayer : castingPlayers)
{
chip::TLV::TLVType castingPlayerContainerType;
// CastingPlayer container starts
ReturnErrorOnFailure(
tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, castingPlayerContainerType));
ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerIdTag), (const uint8_t *) castingPlayer.GetId(),
static_cast<uint32_t>(strlen(castingPlayer.GetId()) + 1)));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerNodeIdTag), castingPlayer.GetNodeId()));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerFabricIndexTag), castingPlayer.GetFabricIndex()));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerVendorIdTag), castingPlayer.GetVendorId()));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerProductIdTag), castingPlayer.GetProductId()));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerDeviceTypeIdTag), castingPlayer.GetDeviceType()));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerSupportsCommissionerGeneratedPasscodeTag),
castingPlayer.GetSupportsCommissionerGeneratedPasscode()));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerPortTag), castingPlayer.GetPort()));
ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerInstanceNameTag),
(const uint8_t *) castingPlayer.GetInstanceName(),
static_cast<uint32_t>(strlen(castingPlayer.GetInstanceName()) + 1)));
ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerDeviceNameTag),
(const uint8_t *) castingPlayer.GetDeviceName(),
static_cast<uint32_t>(strlen(castingPlayer.GetDeviceName()) + 1)));
ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerHostNameTag),
(const uint8_t *) castingPlayer.GetHostName(),
static_cast<uint32_t>(strlen(castingPlayer.GetHostName()) + 1)));
// Endpoints container starts
chip::TLV::TLVType endpointsContainerType;
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointsContainerTag),
chip::TLV::kTLVType_Array, endpointsContainerType));
std::vector<memory::Strong<core::Endpoint>> endpoints = core::CastingPlayer::GetTargetCastingPlayer()->GetEndpoints();
for (auto & endpoint : endpoints)
{
chip::TLV::TLVType endpointContainerType;
// Endpoint container starts
ReturnErrorOnFailure(
tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, endpointContainerType));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointIdTag), endpoint->GetId()));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointVendorIdTag), endpoint->GetVendorId()));
ReturnErrorOnFailure(
tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointProductIdTag), endpoint->GetProductId()));
// DeviceTypeList container starts
chip::TLV::TLVType deviceTypeListContainerType;
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointDeviceTypeListContainerTag),
chip::TLV::kTLVType_Array, deviceTypeListContainerType));
std::vector<chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType> deviceTypeList =
endpoint->GetDeviceTypeList();
for (chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType deviceTypeStruct : deviceTypeList)
{
chip::TLV::TLVType deviceTypeStructContainerType;
// DeviceTypeStruct container starts
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure,
deviceTypeStructContainerType));
ReturnErrorOnFailure(
tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointDeviceTypeTag), deviceTypeStruct.deviceType));
ReturnErrorOnFailure(
tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointDeviceTypeRevisionTag), deviceTypeStruct.revision));
// DeviceTypeStruct container ends
ReturnErrorOnFailure(tlvWriter.EndContainer(deviceTypeStructContainerType));
}
// DeviceTypeList container ends
ReturnErrorOnFailure(tlvWriter.EndContainer(deviceTypeListContainerType));
// ServerList container starts
chip::TLV::TLVType serverListContainerType;
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointServerListContainerTag),
chip::TLV::kTLVType_Structure, serverListContainerType));
std::vector<chip::ClusterId> serverList = endpoint->GetServerList();
for (chip::ClusterId clusterId : serverList)
{
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointServerClusterIdTag), clusterId));
}
// ServerList container ends
ReturnErrorOnFailure(tlvWriter.EndContainer(serverListContainerType));
// Endpoint container ends
ReturnErrorOnFailure(tlvWriter.EndContainer(endpointContainerType));
}
// Endpoints container ends
ReturnErrorOnFailure(tlvWriter.EndContainer(endpointsContainerType));
// CastingPlayer container ends
ReturnErrorOnFailure(tlvWriter.EndContainer(castingPlayerContainerType));
}
// CastingPlayers container ends
ReturnErrorOnFailure(tlvWriter.EndContainer(castingPlayersContainerType));
ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType));
ReturnErrorOnFailure(tlvWriter.Finalize());
ChipLogProgress(AppServer,
"CastingStore::WriteAll TLV(CastingStoreData).LengthWritten: %d bytes, CastingPlayers size: %lu "
"and version: %d",
tlvWriter.GetLengthWritten(), static_cast<unsigned long>(castingPlayers.size()),
kCurrentCastingStoreDataVersion);
return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(kCastingStoreDataKey, castingStoreData,
tlvWriter.GetLengthWritten());
}
CHIP_ERROR CastingStore::DeleteAll()
{
ChipLogProgress(AppServer, "CastingStore::DeleteAll called");
CHIP_ERROR err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(kCastingStoreDataKey);
if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) // no error, if the key-value pair was not stored
{
ChipLogProgress(AppServer, "CastingStore::DeleteAll ignoring error %" CHIP_ERROR_FORMAT, err.Format());
return CHIP_NO_ERROR;
}
return err;
}
CHIP_ERROR CastingStore::Delete(core::CastingPlayer castingPlayer)
{
ChipLogProgress(AppServer, "CastingStore::Delete");
// Read cache of CastingPlayers
std::vector<core::CastingPlayer> castingPlayers = ReadAll();
// search for castingPlayer in CastingStore cache and delete it, if found
if (castingPlayers.size() != 0)
{
auto it = std::find_if(
castingPlayers.begin(), castingPlayers.end(),
[castingPlayer](const core::CastingPlayer & castingPlayerParam) { return castingPlayerParam == castingPlayer; });
if (it != castingPlayers.end())
{
ChipLogProgress(AppServer, "CastingStore::Delete deleting CastingPlayer %s from CastingStore cache", it->GetId());
castingPlayers.erase(it);
return WriteAll(castingPlayers);
}
}
return CHIP_NO_ERROR;
}
void CastingStore::OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex)
{
ChipLogProgress(AppServer, "CastingStore::OnFabricRemoved");
// Read cache of CastingPlayers
std::vector<core::CastingPlayer> castingPlayers = ReadAll();
// search for castingPlayer in CastingStore cache and delete it, if found
if (castingPlayers.size() != 0)
{
auto it = std::find_if(castingPlayers.begin(), castingPlayers.end(),
[fabricIndex](const core::CastingPlayer & castingPlayerParam) {
return castingPlayerParam.GetFabricIndex() == fabricIndex;
});
if (it != castingPlayers.end())
{
ChipLogProgress(AppServer, "CastingStore::OnFabricRemoved deleting CastingPlayer %s from CastingStore cache",
it->GetId());
castingPlayers.erase(it);
WriteAll(castingPlayers);
}
}
}
}; // namespace support
}; // namespace casting
}; // namespace matter