Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tv-casting-app cancel connection upon CancelPasscode CDC message from TV #35331

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/tv-casting-app/linux/simple-app-helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down
47 changes: 39 additions & 8 deletions examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,19 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa
"CommissionerDeclarationHandler");
// Set the callback for handling CommissionerDeclaration messages.
matter::casting::core::CommissionerDeclarationHandler::GetInstance()->SetCommissionerDeclarationCallback(
connectionCallbacks.mCommissionerDeclarationCallback);
connectionCallbacks.mCommissionerDeclarationCallback, mTargetCastingPlayer);
mClientProvidedCommissionerDeclarationCallback = true;
}
else
{
ChipLogProgress(
AppServer,
"CastingPlayer::VerifyOrEstablishConnection() CommissionerDeclarationCallback not provided in ConnectionCallbacks");
// Still set the target casting player in the CommissionerDeclarationHandler in case the we receive a Commissioner
// Delaration message with CancelPasscode.
matter::casting::core::CommissionerDeclarationHandler::GetInstance()->SetCommissionerDeclarationCallback(
nullptr, mTargetCastingPlayer);
mClientProvidedCommissionerDeclarationCallback = false;
}

ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() verifying User Directed Commissioning (UDC) state");
Expand Down Expand Up @@ -225,16 +231,20 @@ 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."););
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;
Expand All @@ -243,6 +253,27 @@ CHIP_ERROR CastingPlayer::StopConnecting()
mTargetCastingPlayer.reset();
CastingPlayerDiscovery::GetInstance()->ClearCastingPlayersInternal();

// shouldSendIdentificationDeclarationMessage is false only when StopConnecting() is called by the casting library.
if (!shouldSendIdentificationDeclarationMessage)
{
ChipLogProgress(AppServer,
"CastingPlayer::StopConnecting() shouldSendIdentificationDeclarationMessage: %s, User Directed "
"Commissioning stopped by CastingPlayer/Commissioner user",
shouldSendIdentificationDeclarationMessage ? "true" : "false");
// If the client has not provided the (Optional) ConnectionCallbacks mCommissionerDeclarationCallback, we can call the
// ConnectionCallbacks mOnConnectionComplete callback with CHIP_ERROR_CONNECTION_ABORTED, to alert the client that the
// commissioning session was cancelled by the CastingPlayer/Commissioner user. For example, in the scenario where user 1 is
// controlling the casting Client/Commissionee and user 2 is controlling the CastingPlayer/Commissioner.
if (!mClientProvidedCommissionerDeclarationCallback)
{
ChipLogProgress(AppServer,
"CastingPlayer::StopConnecting() CommissionerDeclarationCallback not provided by client, calling "
"mOnConnectionComplete with CHIP_ERROR_CONNECTION_ABORTED");
mOnCompleted(CHIP_ERROR_CONNECTION_ABORTED, nullptr);
}
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.
Expand All @@ -251,9 +282,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)
Expand Down
37 changes: 31 additions & 6 deletions examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,14 @@ class CastingPlayer : public std::enable_shared_from_this<CastingPlayer>
/**
* @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();

Expand Down Expand Up @@ -295,6 +297,28 @@ class CastingPlayer : public std::enable_shared_from_this<CastingPlayer>
static memory::Weak<CastingPlayer> 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
Expand Down Expand Up @@ -329,6 +353,7 @@ class CastingPlayer : public std::enable_shared_from_this<CastingPlayer>
// and connect to a CastingPlayer
friend class support::ChipDeviceEventHandler;

friend class CommissionerDeclarationHandler;
friend class ConnectionContext;
friend class support::EndpointListLoader;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "CommissionerDeclarationHandler.h"

#include "CastingPlayer.h"
#include "Types.h"
#include "support/ChipDeviceEventHandler.h"
#include <app/server/Server.h>
Expand Down Expand Up @@ -50,6 +51,25 @@ 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 user has decided to exit the commissioning process on the CastingPlayer/Commissioner, we cancel the ongoing
// connection attempt without notifying the CastingPlayer/Commissioner.
if (auto sharedPtr = mTargetCastingPlayer.lock())
{
CHIP_ERROR err = sharedPtr->StopConnecting(false);
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer,
"CommissionerDeclarationHandler::OnCommissionerDeclarationMessage() Failed to StopConnecting");
}
}
}

if (mCmmissionerDeclarationCallback_)
{
mCmmissionerDeclarationCallback_(source, cd);
Expand All @@ -62,10 +82,14 @@ void CommissionerDeclarationHandler::OnCommissionerDeclarationMessage(
}

void CommissionerDeclarationHandler::SetCommissionerDeclarationCallback(
matter::casting::core::CommissionerDeclarationCallback callback)
matter::casting::core::CommissionerDeclarationCallback callback, memory::Weak<CastingPlayer> castingPlayer)
{
ChipLogProgress(AppServer, "CommissionerDeclarationHandler::SetCommissionerDeclarationCallback()");
mCmmissionerDeclarationCallback_ = std::move(callback);
if (callback != nullptr)
{
mCmmissionerDeclarationCallback_ = std::move(callback);
}
mTargetCastingPlayer = castingPlayer;
}

} // namespace core
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class CommissionerDeclarationHandler : public chip::Protocols::UserDirectedCommi
/**
* @brief OnCommissionerDeclarationMessage() will call the CommissionerDeclarationCallback set by this function.
*/
void SetCommissionerDeclarationCallback(CommissionerDeclarationCallback callback);
void SetCommissionerDeclarationCallback(CommissionerDeclarationCallback callback, memory::Weak<CastingPlayer> castingPlayer);

/**
* @brief returns true if the CommissionerDeclarationHandler sigleton has a CommissionerDeclarationCallback set, false
Expand All @@ -59,6 +59,7 @@ class CommissionerDeclarationHandler : public chip::Protocols::UserDirectedCommi
private:
static CommissionerDeclarationHandler * sCommissionerDeclarationHandler_;
CommissionerDeclarationCallback mCmmissionerDeclarationCallback_;
memory::Weak<CastingPlayer> mTargetCastingPlayer;

CommissionerDeclarationHandler() {}
~CommissionerDeclarationHandler() {}
Expand Down
Loading