From 238570069f5e8bdf5a4d2197aa28f8787992f59b Mon Sep 17 00:00:00 2001 From: Sharad Binjola <31142146+sharadb-amazon@users.noreply.github.com> Date: Thu, 5 Jan 2023 06:49:14 -0800 Subject: [PATCH] tv-casting-app: On kBindingsChangedViaCluster, connect to VideoPlayer if already commissioned with it (#24268) * tv-casting-app: On kBindingsChangedViaCluster, connect to VideoPlayer if already commissioned with it * Addressing chrisdecenzo@'s feedback * Addressing bzbarsky-apple@'s feedback --- .../tv-casting-common/include/CastingServer.h | 3 +- .../include/TargetVideoPlayerInfo.h | 1 + .../tv-casting-common/src/CastingServer.cpp | 73 ++++++++++++++++++- .../src/TargetVideoPlayerInfo.cpp | 27 ++++--- 4 files changed, 90 insertions(+), 14 deletions(-) diff --git a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h index 09fb76d21525df..0eab5ab0311dcb 100644 --- a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h +++ b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h @@ -415,7 +415,8 @@ class CastingServer void ReadServerClusters(chip::EndpointId endpointId); PersistenceManager mPersistenceManager; - bool mInited = false; + bool mInited = false; + bool mUdcInProgress = false; TargetVideoPlayerInfo mActiveTargetVideoPlayerInfo; TargetVideoPlayerInfo mCachedTargetVideoPlayerInfo[kMaxCachedVideoPlayers]; uint16_t mTargetVideoPlayerVendorId = 0; 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 c362ec95c99a24..4c0fd1455e7ea1 100644 --- a/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h +++ b/examples/tv-casting-app/tv-casting-common/include/TargetVideoPlayerInfo.h @@ -43,6 +43,7 @@ class TargetVideoPlayerInfo size_t GetNumIPs() const { return mNumIPs; } const chip::Inet::IPAddress * GetIpAddresses() const { return mIpAddress; } bool IsSameAs(const chip::Dnssd::DiscoveredNodeData * discoveredNodeData); + bool IsSameAs(const char * deviceName, size_t numIPs, const chip::Inet::IPAddress * ipAddresses); chip::OperationalDeviceProxy * GetOperationalDeviceProxy() { 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 1fa2965abcbff6..558139f3cff155 100644 --- a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp +++ b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp @@ -130,6 +130,7 @@ CHIP_ERROR CastingServer::SendUserDirectedCommissioningRequest(chip::Transport:: CHIP_ERROR CastingServer::SendUserDirectedCommissioningRequest(Dnssd::DiscoveredNodeData * selectedCommissioner) { + mUdcInProgress = true; // Send User Directed commissioning request ReturnErrorOnFailure(SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP( selectedCommissioner->resolutionData.ipAddress[0], selectedCommissioner->resolutionData.port, @@ -320,24 +321,92 @@ CastingServer::ContentLauncherLaunchURL(TargetEndpointInfo * endpoint, const cha void CastingServer::DeviceEventCallback(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) { + bool runPostCommissioning = false; + chip::NodeId targetPeerNodeId = 0; + chip::FabricIndex targetFabricIndex = 0; if (event->Type == DeviceLayer::DeviceEventType::kBindingsChangedViaCluster) { + ChipLogProgress(AppServer, "CastingServer::DeviceEventCallback kBindingsChangedViaCluster received"); if (CastingServer::GetInstance()->GetActiveTargetVideoPlayer()->IsInitialized()) { + ChipLogProgress(AppServer, + "CastingServer::DeviceEventCallback already connected to video player, reading server clusters"); CastingServer::GetInstance()->ReadServerClustersForNode( CastingServer::GetInstance()->GetActiveTargetVideoPlayer()->GetNodeId()); } + else if (CastingServer::GetInstance()->mUdcInProgress) + { + ChipLogProgress(AppServer, + "CastingServer::DeviceEventCallback UDC is in progress while handling kBindingsChangedViaCluster"); + CastingServer::GetInstance()->mUdcInProgress = false; + if (CastingServer::GetInstance()->mTargetVideoPlayerNumIPs > 0) + { + TargetVideoPlayerInfo * connectableVideoPlayerList = + CastingServer::GetInstance()->ReadCachedTargetVideoPlayerInfos(); + if (connectableVideoPlayerList == nullptr || !connectableVideoPlayerList[0].IsInitialized()) + { + ChipLogError(AppServer, "CastingServer::DeviceEventCallback No cached video players found"); + CastingServer::GetInstance()->mCommissioningCompleteCallback(CHIP_ERROR_INCORRECT_STATE); + return; + } + + for (size_t i = 0; i < kMaxCachedVideoPlayers && connectableVideoPlayerList[i].IsInitialized(); i++) + { + if (connectableVideoPlayerList[i].IsSameAs(CastingServer::GetInstance()->mTargetVideoPlayerDeviceName, + CastingServer::GetInstance()->mTargetVideoPlayerNumIPs, + CastingServer::GetInstance()->mTargetVideoPlayerIpAddress)) + { + ChipLogProgress(AppServer, + "CastingServer::DeviceEventCallback found the video player to initialize/connect to"); + targetPeerNodeId = connectableVideoPlayerList[i].GetNodeId(); + targetFabricIndex = connectableVideoPlayerList[i].GetFabricIndex(); + runPostCommissioning = true; + } + } + + if (targetPeerNodeId == 0 && runPostCommissioning == false) + { + ChipLogError(AppServer, + "CastingServer::DeviceEventCallback did NOT find the video player to initialize/connect to"); + CastingServer::GetInstance()->mCommissioningCompleteCallback(CHIP_ERROR_INCORRECT_STATE); + return; + } + } + } } else if (event->Type == DeviceLayer::DeviceEventType::kCommissioningComplete) { + ChipLogProgress(AppServer, "CastingServer::DeviceEventCallback kCommissioningComplete received"); + CastingServer::GetInstance()->mUdcInProgress = false; + targetPeerNodeId = event->CommissioningComplete.nodeId; + targetFabricIndex = event->CommissioningComplete.fabricIndex; + runPostCommissioning = true; + } + + if (runPostCommissioning) + { + ChipLogProgress(AppServer, + "CastingServer::DeviceEventCallback will connect with nodeId=0x" ChipLogFormatX64 " fabricIndex=%d", + ChipLogValueX64(targetPeerNodeId), targetFabricIndex); CHIP_ERROR err = CastingServer::GetInstance()->GetActiveTargetVideoPlayer()->Initialize( - event->CommissioningComplete.nodeId, event->CommissioningComplete.fabricIndex, - CastingServer::GetInstance()->mOnConnectionSuccessClientCallback, + targetPeerNodeId, targetFabricIndex, CastingServer::GetInstance()->mOnConnectionSuccessClientCallback, CastingServer::GetInstance()->mOnConnectionFailureClientCallback, CastingServer::GetInstance()->mTargetVideoPlayerVendorId, CastingServer::GetInstance()->mTargetVideoPlayerProductId, CastingServer::GetInstance()->mTargetVideoPlayerDeviceType, CastingServer::GetInstance()->mTargetVideoPlayerDeviceName, CastingServer::GetInstance()->mTargetVideoPlayerNumIPs, CastingServer::GetInstance()->mTargetVideoPlayerIpAddress); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to initialize target video player"); + } + + err = CastingServer::GetInstance()->mPersistenceManager.AddVideoPlayer( + &CastingServer::GetInstance()->mActiveTargetVideoPlayerInfo); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "AddVideoPlayer(ToCache) error: %" CHIP_ERROR_FORMAT, err.Format()); + } + CastingServer::GetInstance()->mCommissioningCompleteCallback(err); } } 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 70609f328fc5ef..7e1d13f7e4677a 100644 --- a/examples/tv-casting-app/tv-casting-common/src/TargetVideoPlayerInfo.cpp +++ b/examples/tv-casting-app/tv-casting-common/src/TargetVideoPlayerInfo.cpp @@ -126,16 +126,10 @@ void TargetVideoPlayerInfo::PrintInfo() } } -bool TargetVideoPlayerInfo::IsSameAs(const chip::Dnssd::DiscoveredNodeData * discoveredNodeData) +bool TargetVideoPlayerInfo::IsSameAs(const char * deviceName, size_t numIPs, const chip::Inet::IPAddress * ipAddresses) { - // return false because 'this' VideoPlayer is not null - if (discoveredNodeData == nullptr) - { - return false; - } - // return false because deviceNames are different - if (strcmp(mDeviceName, discoveredNodeData->commissionData.deviceName) != 0) + if (strcmp(mDeviceName, deviceName) != 0) { return false; } @@ -146,10 +140,9 @@ bool TargetVideoPlayerInfo::IsSameAs(const chip::Dnssd::DiscoveredNodeData * dis bool matchFound = false; for (size_t i = 0; i < mNumIPs && i < chip::Dnssd::CommonResolutionData::kMaxIPAddresses; i++) { - for (size_t j = 0; - j < discoveredNodeData->resolutionData.numIPs && j < chip::Dnssd::CommonResolutionData::kMaxIPAddresses; j++) + for (size_t j = 0; j < numIPs && j < chip::Dnssd::CommonResolutionData::kMaxIPAddresses; j++) { - if (mIpAddress[i] == discoveredNodeData->resolutionData.ipAddress[j]) + if (mIpAddress[i] == ipAddresses[j]) { matchFound = true; break; @@ -169,3 +162,15 @@ bool TargetVideoPlayerInfo::IsSameAs(const chip::Dnssd::DiscoveredNodeData * dis return true; } + +bool TargetVideoPlayerInfo::IsSameAs(const chip::Dnssd::DiscoveredNodeData * discoveredNodeData) +{ + // return false because 'this' VideoPlayer is not null + if (discoveredNodeData == nullptr) + { + return false; + } + + return IsSameAs(discoveredNodeData->commissionData.deviceName, discoveredNodeData->resolutionData.numIPs, + discoveredNodeData->resolutionData.ipAddress); +}