From 48013546afe55c42c53d886e677650bbeae60f23 Mon Sep 17 00:00:00 2001 From: Philip Gregor <147669098+pgregorr-amazon@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:42:16 -0400 Subject: [PATCH] tv-casting-app cancel connection upon CancelPasscode CDC message from TV (#35331) * tv-casting-app cancel connection upon CancelPasscode CDC message from TV * Addressed comments by sharadb-amazon * Fix iOS app crash due to null cpp cluster --- .../MatterTvCastingBridge/MCEndpoint.mm | 72 ++++++++++++++----- ...ionBasicReadVendorIDExampleViewModel.swift | 2 +- ...entLauncherLaunchURLExampleViewModel.swift | 2 +- ...scribeToCurrentStateExampleViewModel.swift | 2 +- .../linux/simple-app-helper.cpp | 2 +- .../tv-casting-common/core/BaseCluster.h | 20 +++++- .../tv-casting-common/core/CastingPlayer.cpp | 35 +++++++-- .../tv-casting-common/core/CastingPlayer.h | 42 ++++++++--- .../core/CommissionerDeclarationHandler.cpp | 39 +++++++++- .../tv-casting-common/core/Endpoint.cpp | 4 +- .../tv-casting-common/core/Endpoint.h | 3 + .../support/CastingStore.cpp | 14 +++- .../support/EndpointListLoader.cpp | 9 ++- 13 files changed, 199 insertions(+), 47 deletions(-) diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCEndpoint.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCEndpoint.mm index 24b5c8639aa6e2..5b26e1575e6177 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCEndpoint.mm +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCEndpoint.mm @@ -90,27 +90,67 @@ - (MCCastingPlayer * _Nonnull)castingPlayer - (MCCluster * _Nullable)clusterForType:(MCEndpointClusterType)type { switch (type) { - case MCEndpointClusterTypeApplicationBasic: - return [[MCApplicationBasicCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster()]; - - case MCEndpointClusterTypeApplicationLauncher: - return [[MCApplicationLauncherCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster()]; - - case MCEndpointClusterTypeContentLauncher: - return [[MCContentLauncherCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster()]; + case MCEndpointClusterTypeApplicationBasic: { + auto cppCluster = _cppEndpoint->GetCluster(); + if (cppCluster == nullptr) { + ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeApplicationBasic, GetCluster() returned nullptr"); + return nil; + } + return [[MCApplicationBasicCluster alloc] initWithCppCluster:cppCluster]; + } - case MCEndpointClusterTypeKeypadInput: - return [[MCKeypadInputCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster()]; + case MCEndpointClusterTypeApplicationLauncher: { + auto cppCluster = _cppEndpoint->GetCluster(); + if (cppCluster == nullptr) { + ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeApplicationLauncher GetCluster() returned nullptr"); + return nil; + } + return [[MCApplicationLauncherCluster alloc] initWithCppCluster:cppCluster]; + } - case MCEndpointClusterTypeMediaPlayback: - return [[MCMediaPlaybackCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster()]; + case MCEndpointClusterTypeContentLauncher: { + auto cppCluster = _cppEndpoint->GetCluster(); + if (cppCluster == nullptr) { + ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeContentLauncher GetCluster() returned nullptr"); + return nil; + } + return [[MCContentLauncherCluster alloc] initWithCppCluster:cppCluster]; + } - case MCEndpointClusterTypeOnOff: - return [[MCOnOffCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster()]; + case MCEndpointClusterTypeKeypadInput: { + auto cppCluster = _cppEndpoint->GetCluster(); + if (cppCluster == nullptr) { + ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeKeypadInput GetCluster() returned nullptr"); + return nil; + } + return [[MCKeypadInputCluster alloc] initWithCppCluster:cppCluster]; + } - case MCEndpointClusterTypeTargetNavigator: - return [[MCTargetNavigatorCluster alloc] initWithCppCluster:_cppEndpoint->GetCluster()]; + case MCEndpointClusterTypeMediaPlayback: { + auto cppCluster = _cppEndpoint->GetCluster(); + if (cppCluster == nullptr) { + ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeMediaPlayback GetCluster() returned nullptr"); + return nil; + } + return [[MCMediaPlaybackCluster alloc] initWithCppCluster:cppCluster]; + } + case MCEndpointClusterTypeOnOff: { + auto cppCluster = _cppEndpoint->GetCluster(); + if (cppCluster == nullptr) { + ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeOnOff GetCluster() returned nullptr"); + return nil; + } + return [[MCOnOffCluster alloc] initWithCppCluster:cppCluster]; + } + case MCEndpointClusterTypeTargetNavigator: { + auto cppCluster = _cppEndpoint->GetCluster(); + if (cppCluster == nullptr) { + ChipLogError(AppServer, "MCEndpoint::clusterForType() MCEndpointClusterTypeTargetNavigator GetCluster() returned nullptr"); + return nil; + } + return [[MCTargetNavigatorCluster alloc] initWithCppCluster:cppCluster]; + } default: ChipLogError(AppServer, "MCEndpointClusterType not found"); break; diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCApplicationBasicReadVendorIDExampleViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCApplicationBasicReadVendorIDExampleViewModel.swift index a95580f5aaf7cd..3efed6baa1289a 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCApplicationBasicReadVendorIDExampleViewModel.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCApplicationBasicReadVendorIDExampleViewModel.swift @@ -47,7 +47,7 @@ class MCApplicationBasicReadVendorIDExampleViewModel: ObservableObject { // validate that the selected endpoint supports the ApplicationBasic cluster if(!endpoint.hasCluster(MCEndpointClusterTypeApplicationBasic)) { - self.Log.error("No ApplicationBasic cluster supporting endpoint found") + self.Log.error("MCApplicationBasicReadVendorIDExampleViewModel.read() No ApplicationBasic cluster supporting endpoint found") DispatchQueue.main.async { self.status = "No ApplicationBasic cluster supporting endpoint found" diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift index aaf18375bb2c82..7f337ed473eb94 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift @@ -47,7 +47,7 @@ class MCContentLauncherLaunchURLExampleViewModel: ObservableObject { // validate that the selected endpoint supports the ContentLauncher cluster if(!endpoint.hasCluster(MCEndpointClusterTypeContentLauncher)) { - self.Log.error("No ContentLauncher cluster supporting endpoint found") + self.Log.error("MCContentLauncherLaunchURLExampleViewModel.invokeCommand() No ContentLauncher cluster supporting endpoint found") DispatchQueue.main.async { self.status = "No ContentLauncher cluster supporting endpoint found" diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.swift index 7a4752431e1846..e699240c49af6c 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.swift @@ -47,7 +47,7 @@ class MCMediaPlaybackSubscribeToCurrentStateExampleViewModel: ObservableObject { // validate that the selected endpoint supports the MediaPlayback cluster if(!endpoint.hasCluster(MCEndpointClusterTypeMediaPlayback)) { - self.Log.error("No MediaPlayback cluster supporting endpoint found") + self.Log.error("MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.subscribe() No MediaPlayback cluster supporting endpoint found") DispatchQueue.main.async { self.status = "No MediaPlayback cluster supporting endpoint found" diff --git a/examples/tv-casting-app/linux/simple-app-helper.cpp b/examples/tv-casting-app/linux/simple-app-helper.cpp index ac60b7fb4740f4..115fe9f7869fc9 100644 --- a/examples/tv-casting-app/linux/simple-app-helper.cpp +++ b/examples/tv-casting-app/linux/simple-app-helper.cpp @@ -267,7 +267,7 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca // For a connection failure, called back with an error and nullptr. VerifyOrReturn( err == CHIP_NO_ERROR, - ChipLogProgress( + ChipLogError( AppServer, "simple-app-helper.cpp::ConnectionHandler(): Failed to connect to CastingPlayer (ID: %s) with err %" CHIP_ERROR_FORMAT, targetCastingPlayer->GetId(), err.Format())); diff --git a/examples/tv-casting-app/tv-casting-common/core/BaseCluster.h b/examples/tv-casting-app/tv-casting-common/core/BaseCluster.h index e98f690cee0087..059bb55ad19800 100644 --- a/examples/tv-casting-app/tv-casting-common/core/BaseCluster.h +++ b/examples/tv-casting-app/tv-casting-common/core/BaseCluster.h @@ -58,12 +58,28 @@ class BaseCluster /** * @return Pointer to the Attribute registered in this cluster, corresponding to attributeId */ - void * GetAttribute(const chip::AttributeId attributeId) { return mAttributes[attributeId]; } + void * GetAttribute(const chip::AttributeId attributeId) + { + if (mAttributes.empty()) + { + ChipLogError(AppServer, "BaseCluster::GetAttribute() mAttributes is empty"); + return nullptr; + } + return mAttributes[attributeId]; + } /** * @return Pointer to the Command registered in this cluster, corresponding to commandId */ - void * GetCommand(const chip::CommandId commandId) { return mCommands[commandId]; } + void * GetCommand(const chip::CommandId commandId) + { + if (mCommands.empty()) + { + ChipLogError(AppServer, "BaseCluster::GetCommand() mCommands is empty"); + return nullptr; + } + return mCommands[commandId]; + } protected: /** diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp index e02e6e7c6946c9..83fc6b4b563a9e 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp @@ -68,12 +68,14 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa // Set the callback for handling CommissionerDeclaration messages. matter::casting::core::CommissionerDeclarationHandler::GetInstance()->SetCommissionerDeclarationCallback( connectionCallbacks.mCommissionerDeclarationCallback); + mClientProvidedCommissionerDeclarationCallback = true; } else { ChipLogProgress( AppServer, "CastingPlayer::VerifyOrEstablishConnection() CommissionerDeclarationCallback not provided in ConnectionCallbacks"); + mClientProvidedCommissionerDeclarationCallback = false; } ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() verifying User Directed Commissioning (UDC) state"); @@ -107,6 +109,7 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa // found the CastingPlayer in cache if (it != cachedCastingPlayers.end()) { + ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() found this CastingPlayer in app cache"); unsigned index = (unsigned int) std::distance(cachedCastingPlayers.begin(), it); if (ContainsDesiredTargetApp(&cachedCastingPlayers[index], idOptions.getTargetAppInfoList())) { @@ -225,16 +228,24 @@ CHIP_ERROR CastingPlayer::ContinueConnecting() CHIP_ERROR CastingPlayer::StopConnecting() { - ChipLogProgress(AppServer, "CastingPlayer::StopConnecting() called, while ChipDeviceEventHandler.sUdcInProgress: %s", - support::ChipDeviceEventHandler::isUdcInProgress() ? "true" : "false"); - VerifyOrReturnValue(mConnectionState == CASTING_PLAYER_CONNECTING, CHIP_ERROR_INCORRECT_STATE, - ChipLogError(AppServer, "CastingPlayer::StopConnecting() called while not in connecting state");); VerifyOrReturnValue( mIdOptions.mCommissionerPasscode, CHIP_ERROR_INCORRECT_STATE, ChipLogError(AppServer, "CastingPlayer::StopConnecting() mIdOptions.mCommissionerPasscode == false, ContinueConnecting() should only " "be called when the CastingPlayer/Commissioner-Generated passcode commissioning flow is in progress.");); + // Calling the internal StopConnecting() API with the shouldSendIdentificationDeclarationMessage set to true to notify the + // CastingPlayer/Commissioner that the commissioning session was cancelled by the Casting Client/Commissionee user. This will + // result in the Casting Client/Commissionee sending a CancelPasscode IdentificationDeclaration message to the CastingPlayer. + // shouldSendIdentificationDeclarationMessage is true when StopConnecting() is called by the Client. + return this->StopConnecting(true); +} +CHIP_ERROR CastingPlayer::StopConnecting(bool shouldSendIdentificationDeclarationMessage) +{ + ChipLogProgress(AppServer, "CastingPlayer::StopConnecting() called, while ChipDeviceEventHandler.sUdcInProgress: %s", + support::ChipDeviceEventHandler::isUdcInProgress() ? "true" : "false"); + VerifyOrReturnValue(mConnectionState == CASTING_PLAYER_CONNECTING, CHIP_ERROR_INCORRECT_STATE, + ChipLogError(AppServer, "CastingPlayer::StopConnecting() called while not in connecting state");); CHIP_ERROR err = CHIP_NO_ERROR; mIdOptions.resetState(); mIdOptions.mCancelPasscode = true; @@ -243,6 +254,16 @@ CHIP_ERROR CastingPlayer::StopConnecting() mTargetCastingPlayer.reset(); CastingPlayerDiscovery::GetInstance()->ClearCastingPlayersInternal(); + if (!shouldSendIdentificationDeclarationMessage) + { + ChipLogProgress(AppServer, + "CastingPlayer::StopConnecting() shouldSendIdentificationDeclarationMessage: %d, User Directed " + "Commissioning aborted by the CastingPlayer/Commissioner user.", + shouldSendIdentificationDeclarationMessage); + resetState(CHIP_ERROR_CONNECTION_ABORTED); + return err; + } + // If a CastingPlayer::ContinueConnecting() error occurs, StopConnecting() can be called while sUdcInProgress == true. // sUdcInProgress should be set to false before sending the CancelPasscode IdentificationDeclaration message to the // CastingPlayer/Commissioner. @@ -251,9 +272,9 @@ CHIP_ERROR CastingPlayer::StopConnecting() support::ChipDeviceEventHandler::SetUdcStatus(false); } - ChipLogProgress( - AppServer, - "CastingPlayer::StopConnecting() calling SendUserDirectedCommissioningRequest() to indicate user canceled passcode entry"); + ChipLogProgress(AppServer, + "CastingPlayer::StopConnecting() calling SendUserDirectedCommissioningRequest() to indicate " + "Client/Commissionee user canceled passcode entry"); #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT err = SendUserDirectedCommissioningRequest(); if (err != CHIP_NO_ERROR) diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h index 4fcb1ea5ca60da..b2422b43f5dee6 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h @@ -102,16 +102,11 @@ class CastingPlayer : public std::enable_shared_from_this */ static CastingPlayer * GetTargetCastingPlayer() { - ChipLogProgress(AppServer, "CastingPlayer::GetTargetCastingPlayer() called"); std::shared_ptr sharedPtr = mTargetCastingPlayer.lock(); CastingPlayer * rawPtr = nullptr; if (sharedPtr) { rawPtr = sharedPtr.get(); - ChipLogProgress( - AppServer, - "CastingPlayer::GetTargetCastingPlayer() Got rawPtr from mTargetCastingPlayer, sharedPtr reference count: %lu", - sharedPtr.use_count()); sharedPtr.reset(); } else @@ -207,12 +202,14 @@ class CastingPlayer : public std::enable_shared_from_this /** * @brief This cancels the CastingPlayer/Commissioner-Generated passcode commissioning flow started via the * VerifyOrEstablishConnection() API above. It constructs and sends an IdentificationDeclaration message to the - * CastingPlayer/Commissioner containing CancelPasscode set to true. It is used to indicate that the user, and thus the - * Client/Commissionee, have cancelled the commissioning process. This indicates that the CastingPlayer/Commissioner can dismiss - * any dialogs corresponding to commissioning, such as a Passcode input dialog or a Passcode display dialog. - * Note: stopConnecting() does not call the ConnectCallback() callback passed to the VerifyOrEstablishConnection() API above - * since no connection is established. - * @return CHIP_NO_ERROR if this function was called with the CastingPlayer in the correct state and an error otherwise. + * CastingPlayer/Commissioner containing CancelPasscode set to true. It is used to indicate that the Client/Commissionee user + * has cancelled the commissioning process. This indicates that the CastingPlayer/Commissioner can dismiss any dialogs + * corresponding to commissioning, such as a Passcode input dialog or a Passcode display dialog. Note: StopConnecting() does not + * call the ConnectCallback() callback passed to the VerifyOrEstablishConnection() API above since no connection is established. + * @return CHIP_NO_ERROR if this function was called with the CastingPlayer in the correct state and CHIP_ERROR_INCORRECT_STATE. + * otherwise. StopConnecting() can only be called by the client during the CastingPlayer/Commissioner-Generated passcode + * commissioning flow. Calling StopConnecting() during the Client/Commissionee-Generated commissioning flow will return a + * CHIP_ERROR_INCORRECT_STATE error. */ CHIP_ERROR StopConnecting(); @@ -295,6 +292,28 @@ class CastingPlayer : public std::enable_shared_from_this static memory::Weak mTargetCastingPlayer; uint16_t mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec; ConnectCallback mOnCompleted = {}; + bool mClientProvidedCommissionerDeclarationCallback; + + /** + * @brief This internal version of the StopConnecting API cancels the Client/Commissionee-Generated passcode or the + * CastingPlayer/Commissioner-Generated passcode commissioning flow started via the VerifyOrEstablishConnection() API above. + * Furthermore, StopConnecting operates in two ways as governed by the shouldSendIdentificationDeclarationMessage flag: + * 1. If shouldSendIdentificationDeclarationMessage is true. StopConnecting constructs and sends an IdentificationDeclaration + * message to the CastingPlayer/Commissioner containing CancelPasscode set to true. The CancelPasscode flag set to true conveys + * that the Client/Commissionee user has cancelled the commissioning session. This indicates that the CastingPlayer/Commissioner + * can dismiss any dialogs corresponding to commissioning, such as a Passcode input dialog or a Passcode display dialog. In this + * case, since StopConnecting was called by the Client/Commissionee, StopConnecting() does not call the ConnectCallback() + * callback passed to the VerifyOrEstablishConnection(). + * 2. If shouldSendIdentificationDeclarationMessage is false. StopConnecting does not send an IdentificationDeclaration message + * to the CastingPlayer/Commissioner since the CastingPlayer/Commissioner notified the Client/Commissionee that the connection + * is aborted. If the (Optional) ConnectionCallbacks mCommissionerDeclarationCallback is not set, it calls ConnectionCallbacks + * mOnConnectionComplete callback with CHIP_ERROR_CONNECTION_ABORTED. + * @param shouldSendIdentificationDeclarationMessage if true, send the IdentificationDeclaration message to the CastingPlayer + * with CancelPasscode set to true. If false, only call the ConnectionCallbacks mCommissionerDeclarationCallback callback passed + * to the VerifyOrEstablishConnection() API above, without sending the IdentificationDeclaration message. + * @return CHIP_NO_ERROR if this function was called with the CastingPlayer in the correct state and an error otherwise. + */ + CHIP_ERROR StopConnecting(bool shouldSendIdentificationDeclarationMessage); /** * @brief resets this CastingPlayer's state and calls mOnCompleted with the CHIP_ERROR. Also, after calling mOnCompleted, it @@ -329,6 +348,7 @@ class CastingPlayer : public std::enable_shared_from_this // and connect to a CastingPlayer friend class support::ChipDeviceEventHandler; + friend class CommissionerDeclarationHandler; friend class ConnectionContext; friend class support::EndpointListLoader; }; diff --git a/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp b/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp index 22e7d49cdb7a5d..c89b899bf5db43 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CommissionerDeclarationHandler.cpp @@ -18,6 +18,7 @@ #include "CommissionerDeclarationHandler.h" +#include "CastingPlayer.h" #include "Types.h" #include "support/ChipDeviceEventHandler.h" #include @@ -50,6 +51,39 @@ void CommissionerDeclarationHandler::OnCommissionerDeclarationMessage( chip::Server::GetInstance().GetCommissioningWindowManager().CloseCommissioningWindow(); support::ChipDeviceEventHandler::SetUdcStatus(false); + // Flag to indicate when the CastingPlayer/Commissioner user has decided to exit the commissioning process. + if (cd.GetCancelPasscode()) + { + ChipLogProgress(AppServer, + "CommissionerDeclarationHandler::OnCommissionerDeclarationMessage(), Got CancelPasscode parameter, " + "CastingPlayer/Commissioner user has decided to exit the commissioning attempt. Connection aborted."); + // Since the CastingPlayer/Commissioner user has decided to exit the commissioning process, we cancel the ongoing + // connection attempt without notifying the CastingPlayer/Commissioner. Therefore the + // shouldSendIdentificationDeclarationMessage flag in the internal StopConnecting() API call is set to false. The + // CastingPlayer/Commissioner user and the Casting Client/Commissionee user are not necessarily the same user. For example, + // in an enviroment with multiple CastingPlayer/Commissioner TVs, one user 1 might be controlling the Client/Commissionee + // and user 2 might be controlling the CastingPlayer/Commissioner TV. + CastingPlayer * targetCastingPlayer = CastingPlayer::GetTargetCastingPlayer(); + // Avoid crashing if we recieve this CommissionerDeclaration message when targetCastingPlayer is nullptr. + if (targetCastingPlayer == nullptr) + { + ChipLogError(AppServer, + "CommissionerDeclarationHandler::OnCommissionerDeclarationMessage() targetCastingPlayer is nullptr"); + } + else + { + CHIP_ERROR err = targetCastingPlayer->StopConnecting(false); + if (err != CHIP_NO_ERROR) + { + ChipLogError( + AppServer, + "CommissionerDeclarationHandler::OnCommissionerDeclarationMessage() StopConnecting() failed due to error: " + "%" CHIP_ERROR_FORMAT, + err.Format()); + } + } + } + if (mCmmissionerDeclarationCallback_) { mCmmissionerDeclarationCallback_(source, cd); @@ -65,7 +99,10 @@ void CommissionerDeclarationHandler::SetCommissionerDeclarationCallback( matter::casting::core::CommissionerDeclarationCallback callback) { ChipLogProgress(AppServer, "CommissionerDeclarationHandler::SetCommissionerDeclarationCallback()"); - mCmmissionerDeclarationCallback_ = std::move(callback); + if (callback != nullptr) + { + mCmmissionerDeclarationCallback_ = std::move(callback); + } } } // namespace core diff --git a/examples/tv-casting-app/tv-casting-common/core/Endpoint.cpp b/examples/tv-casting-app/tv-casting-common/core/Endpoint.cpp index d2fb12e48daf68..25b9e2850edb56 100644 --- a/examples/tv-casting-app/tv-casting-common/core/Endpoint.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/Endpoint.cpp @@ -28,6 +28,7 @@ void Endpoint::RegisterClusters(std::vector clusters) { for (chip::ClusterId clusterId : clusters) { + ChipLogProgress(AppServer, "Endpoint::RegisterClusters() Registering clusterId %d for endpointId %d", clusterId, GetId()); switch (clusterId) { case chip::app::Clusters::ApplicationBasic::Id: @@ -67,7 +68,8 @@ void Endpoint::RegisterClusters(std::vector clusters) break; default: - ChipLogProgress(AppServer, "Skipping registration of clusterId %d for endpointId %d", clusterId, GetId()); + ChipLogProgress(AppServer, "Endpoint::RegisterClusters() Skipping registration of clusterId %d for endpointId %d", + clusterId, GetId()); break; } } diff --git a/examples/tv-casting-app/tv-casting-common/core/Endpoint.h b/examples/tv-casting-app/tv-casting-common/core/Endpoint.h index fc18267cf466be..734f1e3d5ae140 100644 --- a/examples/tv-casting-app/tv-casting-common/core/Endpoint.h +++ b/examples/tv-casting-app/tv-casting-common/core/Endpoint.h @@ -105,6 +105,7 @@ class Endpoint : public std::enable_shared_from_this */ std::vector GetServerList() { + ChipLogProgress(AppServer, "Endpoint::GetServerList() mClusters.size(): %d", static_cast(mClusters.size())); std::vector serverList; for (auto const & cluster : mClusters) { @@ -122,6 +123,7 @@ class Endpoint : public std::enable_shared_from_this template void RegisterCluster(const chip::ClusterId clusterId) { + ChipLogProgress(AppServer, "Endpoint::RegisterCluster() Registering clusterId %d for endpointId %d", clusterId, GetId()); static_assert(std::is_base_of::value, "T must be derived from BaseCluster"); auto cluster = std::make_shared(shared_from_this()); cluster->SetUp(); @@ -135,6 +137,7 @@ class Endpoint : public std::enable_shared_from_this memory::Strong GetCluster() { static_assert(std::is_base_of::value, "T must be derived from BaseCluster"); + ChipLogProgress(AppServer, "Endpoint::GetCluster() mClusters.size(): %d", static_cast(mClusters.size())); for (const auto & pair : mClusters) { auto cluster = std::dynamic_pointer_cast(pair.second); diff --git a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp index 2e8561d2e5aab1..93bd00616dac6c 100644 --- a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp +++ b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp @@ -427,9 +427,14 @@ std::vector CastingStore::ReadAll() for (auto & endpointAttributes : endpointAttributesList) { std::shared_ptr endpoint(new core::Endpoint(castingPlayer, endpointAttributes)); + ChipLogProgress(AppServer, "CastingStore::ReadAll() endpointServerListMap[endpointAttributes.mId].size(): %d", + static_cast(endpointServerListMap[endpointAttributes.mId].size())); endpoint->RegisterClusters(endpointServerListMap[endpointAttributes.mId]); castingPlayer->RegisterEndpoint(endpoint); + ChipLogProgress(AppServer, "CastingStore::ReadAll() Registered endpointID: %d", endpoint->GetId()); } + ChipLogProgress(AppServer, "CastingStore::ReadAll() Created CastingPlayer with deviceName: %s", + castingPlayer->GetDeviceName()); castingPlayers.push_back(*castingPlayer); continue; } @@ -453,7 +458,7 @@ std::vector CastingStore::ReadAll() CHIP_ERROR CastingStore::WriteAll(std::vector castingPlayers) { - ChipLogProgress(AppServer, "CastingStore::WriteAll called"); + ChipLogProgress(AppServer, "CastingStore::WriteAll() called"); chip::TLV::TLVWriter tlvWriter; uint8_t castingStoreData[kCastingStoreDataMaxBytes]; @@ -470,6 +475,7 @@ CHIP_ERROR CastingStore::WriteAll(std::vector castingPlayer for (auto & castingPlayer : castingPlayers) { + ChipLogProgress(AppServer, "CastingStore::WriteAll() writing castingPlayer:"); chip::TLV::TLVType castingPlayerContainerType; // CastingPlayer container starts ReturnErrorOnFailure( @@ -502,6 +508,8 @@ CHIP_ERROR CastingStore::WriteAll(std::vector castingPlayer std::vector> endpoints = core::CastingPlayer::GetTargetCastingPlayer()->GetEndpoints(); for (auto & endpoint : endpoints) { + ChipLogProgress(AppServer, "CastingStore::WriteAll() writing CastingPlayer Endpoint with endpointId: %d", + endpoint->GetId()); chip::TLV::TLVType endpointContainerType; // Endpoint container starts ReturnErrorOnFailure( @@ -539,8 +547,10 @@ CHIP_ERROR CastingStore::WriteAll(std::vector castingPlayer ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointServerListContainerTag), chip::TLV::kTLVType_Structure, serverListContainerType)); std::vector serverList = endpoint->GetServerList(); + ChipLogProgress(AppServer, "CastingStore::WriteAll() writing CastingPlayer Endpoint ServerList:"); for (chip::ClusterId clusterId : serverList) { + ChipLogProgress(AppServer, "CastingStore::WriteAll() clusterId: %d", clusterId); ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointServerClusterIdTag), clusterId)); } // ServerList container ends @@ -562,7 +572,7 @@ CHIP_ERROR CastingStore::WriteAll(std::vector castingPlayer ReturnErrorOnFailure(tlvWriter.Finalize()); ChipLogProgress(AppServer, - "CastingStore::WriteAll TLV(CastingStoreData).LengthWritten: %d bytes, CastingPlayers size: %lu " + "CastingStore::WriteAll() TLV(CastingStoreData).LengthWritten: %d bytes, CastingPlayers size: %lu " "and version: %d", tlvWriter.GetLengthWritten(), static_cast(castingPlayers.size()), kCurrentCastingStoreDataVersion); diff --git a/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp b/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp index a7bbfb78d6ad3a..7d32456ad534fc 100644 --- a/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp +++ b/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp @@ -90,7 +90,8 @@ CHIP_ERROR EndpointListLoader::Load() if (binding.type == MATTER_UNICAST_BINDING && CastingPlayer::GetTargetCastingPlayer()->GetNodeId() == binding.nodeId) { // if we discovered a new Endpoint from the bindings, read its EndpointAttributes - chip::EndpointId endpointId = binding.remote; + chip::EndpointId endpointId = binding.remote; + ChipLogProgress(AppServer, "EndpointListLoader::Load() Found new endpointId: %d", endpointId); std::vector> endpoints = CastingPlayer::GetTargetCastingPlayer()->GetEndpoints(); if (std::find_if(endpoints.begin(), endpoints.end(), [&endpointId](const memory::Strong & endpoint) { return endpoint->GetId() == endpointId; @@ -128,17 +129,19 @@ void EndpointListLoader::Complete() if (mPendingAttributeReads == 0) { - ChipLogProgress(AppServer, "EndpointListLoader::Complete Loading %lu endpoint(s)", mNewEndpointsToLoad); + ChipLogProgress(AppServer, "EndpointListLoader::Complete() Loading %lu endpoint(s)", mNewEndpointsToLoad); for (unsigned long i = 0; i < mNewEndpointsToLoad; i++) { EndpointAttributes endpointAttributes = mEndpointAttributesList[i]; std::shared_ptr endpoint = std::make_shared(CastingPlayer::GetTargetCastingPlayer(), endpointAttributes); + ChipLogProgress(AppServer, "EndpointListLoader::Complete() mEndpointServerLists[i].size: %lu ", + mEndpointServerLists[i].size()); endpoint->RegisterClusters(mEndpointServerLists[i]); CastingPlayer::GetTargetCastingPlayer()->RegisterEndpoint(endpoint); } - ChipLogProgress(AppServer, "EndpointListLoader::Complete finished Loading %lu endpoints", mNewEndpointsToLoad); + ChipLogProgress(AppServer, "EndpointListLoader::Complete() Finished Loading %lu endpoints", mNewEndpointsToLoad); // TODO cleanup // delete mEndpointAttributesList;