diff --git a/examples/tv-casting-app/tv-casting-common/include/PersistenceManager.h b/examples/tv-casting-app/tv-casting-common/include/PersistenceManager.h index 6d3f36b7801416..f0774c3d0a2c23 100644 --- a/examples/tv-casting-app/tv-casting-common/include/PersistenceManager.h +++ b/examples/tv-casting-app/tv-casting-common/include/PersistenceManager.h @@ -23,13 +23,15 @@ constexpr size_t kMaxCachedVideoPlayers = 32; -class PersistenceManager +class PersistenceManager : public chip::FabricTable::Delegate { public: CHIP_ERROR AddVideoPlayer(TargetVideoPlayerInfo * targetVideoPlayerInfo); CHIP_ERROR ReadAllVideoPlayers(TargetVideoPlayerInfo outVideoPlayers[]); + void OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex); + CHIP_ERROR PurgeVideoPlayerCache(); private: diff --git a/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h b/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h index c0722dc0f2dcad..edde7abf36521c 100644 --- a/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h +++ b/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h @@ -69,6 +69,7 @@ class TargetVideoPlayerInfo bool operator==(const TargetVideoPlayerInfo & other) { return this->mNodeId == other.mNodeId; } bool IsInitialized() { return mInitialized; } + void Reset(); uint16_t GetVendorId() const { return mVendorId; } uint16_t GetProductId() const { return mProductId; } chip::DeviceTypeId GetDeviceType() const { return mDeviceType; } diff --git a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp index 1dd4612b03f1db..0a23c889d624fb 100644 --- a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp +++ b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp @@ -57,6 +57,9 @@ CHIP_ERROR CastingServer::Init(AppParams * AppParams) // Initialize binding handlers ReturnErrorOnFailure(InitBindingHandlers()); + // Set FabricDelegate + chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&mPersistenceManager); + // Add callback to send Content casting commands after commissioning completes ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(DeviceEventCallback, 0)); diff --git a/examples/tv-casting-app/tv-casting-common/src/PersistenceManager.cpp b/examples/tv-casting-app/tv-casting-common/src/PersistenceManager.cpp index 347543c87018cb..32d4cbbfe2fb02 100644 --- a/examples/tv-casting-app/tv-casting-common/src/PersistenceManager.cpp +++ b/examples/tv-casting-app/tv-casting-common/src/PersistenceManager.cpp @@ -402,6 +402,48 @@ CHIP_ERROR PersistenceManager::ReadAllVideoPlayers(TargetVideoPlayerInfo outVide return CHIP_NO_ERROR; } +void PersistenceManager::OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) +{ + ChipLogProgress(AppServer, "PersistenceManager::OnFabricRemoved called for fabricIndex: %d", fabricIndex); + + // Read cached video players + TargetVideoPlayerInfo cachedVideoPlayers[kMaxCachedVideoPlayers]; + CHIP_ERROR err = ReadAllVideoPlayers(cachedVideoPlayers); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "PersistenceManager::OnFabricRemoved could not read cached video players %" CHIP_ERROR_FORMAT, + err.Format()); + } + + // Delete video players that match the passed in fabricIndex + for (size_t i = 0; i < kMaxCachedVideoPlayers && cachedVideoPlayers[i].IsInitialized(); i++) + { + if (cachedVideoPlayers[i].GetFabricIndex() == fabricIndex) + { + ChipLogProgress(AppServer, + "PersistenceManager::OnFabricRemoved removing video player with nodeId: 0x" ChipLogFormatX64 + " from cache", + ChipLogValueX64(cachedVideoPlayers[i].GetNodeId())); + + // shift elements back by 1 and mark the last array element for deletion + size_t indexToDelete = i; + if (indexToDelete + 1 < kMaxCachedVideoPlayers && cachedVideoPlayers[indexToDelete + 1].IsInitialized()) + { + while (indexToDelete + 1 < kMaxCachedVideoPlayers && cachedVideoPlayers[indexToDelete + 1].IsInitialized()) + { + cachedVideoPlayers[indexToDelete] = cachedVideoPlayers[indexToDelete + 1]; + indexToDelete++; + } + } + + // Reset cachedVideoPlayers[indexToDelete] + cachedVideoPlayers[indexToDelete].Reset(); + } + } + + WriteAllVideoPlayers(cachedVideoPlayers); +} + CHIP_ERROR PersistenceManager::PurgeVideoPlayerCache() { ChipLogProgress(AppServer, "PersistenceManager::PurgeVideoPlayerCache called"); diff --git a/examples/tv-casting-app/tv-casting-common/src/TargetVideoPlayerInfo.cpp b/examples/tv-casting-app/tv-casting-common/src/TargetVideoPlayerInfo.cpp index ae51105a96d3bb..c075a34c218f91 100644 --- a/examples/tv-casting-app/tv-casting-common/src/TargetVideoPlayerInfo.cpp +++ b/examples/tv-casting-app/tv-casting-common/src/TargetVideoPlayerInfo.cpp @@ -68,6 +68,29 @@ CHIP_ERROR TargetVideoPlayerInfo::Initialize(NodeId nodeId, FabricIndex fabricIn return CHIP_NO_ERROR; } +void TargetVideoPlayerInfo::Reset() +{ + ChipLogProgress(NotSpecified, "TargetVideoPlayerInfo Reset() called"); + mInitialized = false; + mNodeId = 0; + mFabricIndex = 0; + mVendorId = 0; + mProductId = 0; + mDeviceType = 0; + memset(mDeviceName, '\0', sizeof(mDeviceName)); + memset(mHostName, '\0', sizeof(mHostName)); + mDeviceProxy = nullptr; + for (auto & endpointInfo : mEndpoints) + { + endpointInfo.Reset(); + } + for (size_t i = 0; i < mNumIPs && i < chip::Dnssd::CommonResolutionData::kMaxIPAddresses; i++) + { + mIpAddress[i] = chip::Inet::IPAddress(); + } + mNumIPs = 0; +} + CHIP_ERROR TargetVideoPlayerInfo::FindOrEstablishCASESession(std::function onConnectionSuccess, std::function onConnectionFailure) {