Skip to content

Commit

Permalink
Added CastingStore:Read/WriteAll
Browse files Browse the repository at this point in the history
  • Loading branch information
sharadb-amazon committed Oct 12, 2023
1 parent 3e6789e commit 0b3b397
Show file tree
Hide file tree
Showing 5 changed files with 354 additions and 12 deletions.
3 changes: 2 additions & 1 deletion examples/tv-casting-app/tv-casting-common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ chip_data_model("tv-casting-common") {
"core/CastingPlayerDiscovery.h",
"core/Types.h",
"support/AppParameters.h",
"support/AppParameters.h",
"support/CastingStore.cpp",
"support/CastingStore.h",
"support/ChipDeviceEventHandler.cpp",
"support/ChipDeviceEventHandler.h",
"support/DataProvider.h",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ inline constexpr chip::System::Clock::Seconds16 kCommissioningWindowTimeout = ch
class CastingPlayerAttributes
{
public:
char id[kIdMaxLength + 1] = {};
char deviceName[chip::Dnssd::kMaxDeviceNameLen + 1] = {};
char hostName[chip::Dnssd::kHostNameMaxLength + 1] = {};
char instanceName[chip::Dnssd::kHostNameMaxLength + 1] = {};
char id[kIdMaxLength + 1] = {};
char deviceName[chip::Dnssd::kMaxDeviceNameLen + 1] = {};
char hostName[chip::Dnssd::kHostNameMaxLength + 1] = {};
char instanceName[chip::Dnssd::Commission::kInstanceNameMaxLength + 1] = {};
unsigned int numIPs; // number of valid IP addresses
chip::Inet::IPAddress ipAddresses[chip::Dnssd::CommonResolutionData::kMaxIPAddresses];
chip::Inet::InterfaceId interfaceId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,13 @@ void DeviceDiscoveryDelegateImpl::OnDiscoveredDevice(const chip::Dnssd::Discover

// convert nodeData to CastingPlayer
CastingPlayerAttributes attributes;
strcpy(attributes.id, nodeData.resolutionData.hostName);
snprintf(attributes.id, kIdMaxLength + 1, "%s%u", nodeData.resolutionData.hostName, nodeData.resolutionData.port);

char port[kPortMaxLength + 1] = {};
snprintf(port, sizeof(port), "%u", nodeData.resolutionData.port);
strcat(attributes.id, port);
chip::Platform::CopyString(attributes.deviceName, chip::Dnssd::kMaxDeviceNameLen + 1, nodeData.commissionData.deviceName);
chip::Platform::CopyString(attributes.hostName, chip::Dnssd::kHostNameMaxLength + 1, nodeData.resolutionData.hostName);
chip::Platform::CopyString(attributes.instanceName, chip::Dnssd::Commission::kInstanceNameMaxLength + 1,
nodeData.commissionData.instanceName);

strcpy(attributes.deviceName, nodeData.commissionData.deviceName);
strcpy(attributes.hostName, nodeData.resolutionData.hostName);
strcpy(attributes.instanceName, nodeData.commissionData.instanceName);
attributes.numIPs = (unsigned int) nodeData.resolutionData.numIPs;
for (unsigned j = 0; j < attributes.numIPs; j++)
{
Expand Down
270 changes: 270 additions & 0 deletions examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/*
*
* 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)
{
return CHIP_NO_ERROR;
}

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 = chip::TLV::kTLVType_Structure;
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 outerContainerTagTagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(outerContainerTag));
VerifyOrReturnValue(outerContainerTagTagNum == 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
chip::TLV::TLVType castingPlayersContainerType = chip::TLV::kTLVType_Array;
err = reader.Next();
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
ChipLogError(AppServer, "TLVReader.Next failed %" CHIP_ERROR_FORMAT, err.Format()));
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 = chip::TLV::kTLVType_Structure;
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;
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 == 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 (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()));
core::CastingPlayer castingPlayer(attributes);
castingPlayers.push_back(castingPlayer);
break;
}
}
}

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::DeleteAll()
{
return CHIP_NO_ERROR;
}

CHIP_ERROR CastingStore::Delete(core::CastingPlayer * castingPlayer)
{
return CHIP_NO_ERROR;
}

void CastingStore::OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex)
{

}

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 = chip::TLV::kTLVType_Structure;
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerContainerType));
ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingStoreDataVersionTag), kCurrentCastingStoreDataVersion));

chip::TLV::TLVType castingPlayersContainerType = chip::TLV::kTLVType_Array;
// CastingPlayers container starts
ReturnErrorOnFailure(
tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayersContainerTag), chip::TLV::kTLVType_Array, castingPlayersContainerType));

for(auto & castingPlayer : castingPlayers)
{
chip::TLV::TLVType castingPlayerContainerType = chip::TLV::kTLVType_Structure;
// CastingPlayer container starts
ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerContainerTag), chip::TLV::kTLVType_Structure, castingPlayerContainerType));

ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerIdTag), castingPlayer.GetId()));
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.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)));
// 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(), castingPlayers.size(), kCurrentCastingStoreDataVersion);
return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(kCastingStoreDataKey, castingStoreData, tlvWriter.GetLengthWritten());
}

}; // namespace support
}; // namespace casting
}; // namespace matter
73 changes: 73 additions & 0 deletions examples/tv-casting-app/tv-casting-common/support/CastingStore.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
*
* 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.
*/

#pragma once

#include "core/CastingPlayer.h"

namespace matter {
namespace casting {
namespace support {

class CastingStore : public chip::FabricTable::Delegate
{
public:
static CastingStore * GetInstance();

CHIP_ERROR AddOrUpdate(core::CastingPlayer * castingPlayer);

std::vector<core::CastingPlayer> ReadAll();

CHIP_ERROR Delete(core::CastingPlayer * castingPlayer);

CHIP_ERROR DeleteAll();

void OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override;

private:
CastingStore();
static CastingStore * _CastingStore;

CHIP_ERROR WriteAll(std::vector<core::CastingPlayer> castingPlayers);

enum CastingStoreTLVTag
{
kCastingStoreDataVersionTag = 1,
kCastingPlayersContainerTag,
kCastingPlayerContainerTag,
kCastingPlayerIdTag,
kCastingPlayerNodeIdTag,
kCastingPlayerFabricIndexTag,
kCastingPlayerVendorIdTag,
kCastingPlayerProductIdTag,
kCastingPlayerDeviceTypeIdTag,
kCastingPlayerDeviceNameTag,
kCastingPlayerHostNameTag,

kContextTagMaxNum = UINT8_MAX
};

constexpr static size_t kCastingStoreDataMaxBytes = 1024 * 100; // 100 KBs
constexpr static char * kCastingStoreDataKey = (char *) "com.matter.casting.CastingStore";
constexpr static uint32_t kCurrentCastingStoreDataVersion = 1;
constexpr static uint32_t kSupportedCastingStoreDataVersions[1] = { 1 };
};

}; // namespace support
}; // namespace casting
}; // namespace matter

0 comments on commit 0b3b397

Please sign in to comment.