Skip to content

Commit

Permalink
Addressed comments by andy31415 and sharadb-amazon
Browse files Browse the repository at this point in the history
  • Loading branch information
pgregorr-amazon committed May 21, 2024
1 parent 85788c7 commit 4918b5e
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ JNI_METHOD(jobject, verifyOrEstablishConnection)
matter::casting::core::ConnectionCallbacks connectionCallbacks;
connectionCallbacks.mOnConnectionComplete = connectCallback;

castingPlayer->VerifyOrEstablishConnection(connectionCallbacks, static_cast<uint64_t>(commissioningWindowTimeoutSec),
castingPlayer->VerifyOrEstablishConnection(connectionCallbacks, static_cast<uint16_t>(commissioningWindowTimeoutSec),
idOptions);
return support::convertMatterErrorFromCppToJava(CHIP_NO_ERROR);
}
Expand Down
28 changes: 11 additions & 17 deletions examples/tv-casting-app/linux/simple-app-helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
// VendorId of the Endpoint on the CastingPlayer that the CastingApp desires to interact with after connection
const uint16_t kDesiredEndpointVendorId = 65521;
// Indicates that the Commissioner-Generated passcode commissioning flow is in progress.
bool gCommissionerGeneratedPasscodeFlow = false;
bool gCommissionerGeneratedPasscodeFlowRunning = false;

DiscoveryDelegateImpl * DiscoveryDelegateImpl::_discoveryDelegateImpl = nullptr;
bool gAwaitingCommissionerPasscodeInput = false;
Expand Down Expand Up @@ -246,19 +246,13 @@ CHIP_ERROR InitCommissionableDataProvider(LinuxCommissionableDataProvider & prov
options.payload.discriminator.GetLongValue());
}

void PrintEndpointsVendorAndProductIDs(
const std::vector<matter::casting::memory::Strong<matter::casting::core::Endpoint>> & endpoints)
void LogEndpointsDetails(const std::vector<matter::casting::memory::Strong<matter::casting::core::Endpoint>> & endpoints)
{
ChipLogProgress(AppServer, "simple-app-helper.cpp::PrintEndpointsVendorAndProductIDs() Number of Endpoints: %d",
ChipLogProgress(AppServer, "simple-app-helper.cpp::LogEndpointsDetails() Number of Endpoints: %d",
static_cast<int>(endpoints.size()));
for (const auto & endpoint : endpoints)
{
int endpointId = endpoint->GetId();
int vendorId = endpoint->GetVendorId();
int productId = endpoint->GetProductId();
ChipLogProgress(AppServer,
"simple-app-helper.cpp::PrintEndpointsVendorAndProductIDs() Endpoint ID: %d, Vendor ID: %d, Product ID: %d",
endpointId, vendorId, productId);
endpoint->LogDetail();
}
}

Expand All @@ -274,7 +268,7 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca
"simple-app-helper.cpp::ConnectionHandler(): Failed to connect to CastingPlayer (ID: %s) with err %" CHIP_ERROR_FORMAT,
targetCastingPlayer->GetId(), err.Format()));

if (gCommissionerGeneratedPasscodeFlow)
if (gCommissionerGeneratedPasscodeFlowRunning)
{
ChipLogProgress(AppServer,
"simple-app-helper.cpp::ConnectionHandler(): Successfully connected to CastingPlayer (ID: %s) using "
Expand All @@ -293,15 +287,15 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca

ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler(): Getting endpoints avaiable for demo interactions");
std::vector<matter::casting::memory::Strong<matter::casting::core::Endpoint>> endpoints = castingPlayer->GetEndpoints();
PrintEndpointsVendorAndProductIDs(endpoints);
LogEndpointsDetails(endpoints);

// Find the desired Endpoint and auto-trigger some Matter Casting demo interactions
auto it = std::find_if(endpoints.begin(), endpoints.end(),
[](const matter::casting::memory::Strong<matter::casting::core::Endpoint> & endpoint) {
if (gCommissionerGeneratedPasscodeFlow)
if (gCommissionerGeneratedPasscodeFlowRunning)
{
// Since the tv-app with Vendor ID 1111 does not implement the endpoint with Vendor ID 65521 we
// will (temporarily) use the first available endpoint for demo interactions. See
// will (temporarily) use the endpoint with ID == 1 for demo interactions. See
// connectedhomeip/examples/tv-app/tv-common/include/AppTv.h.
return endpoint->GetId() == 1;
}
Expand Down Expand Up @@ -394,7 +388,7 @@ CHIP_ERROR CommandHandler(int argc, char ** argv)
ChipLogError(AppServer, "Invalid casting player index provided: %lu", index));
targetCastingPlayer = castingPlayers.at(index);

gCommissionerGeneratedPasscodeFlow = false;
gCommissionerGeneratedPasscodeFlowRunning = false;
matter::casting::core::IdentificationDeclarationOptions idOptions;
chip::Protocols::UserDirectedCommissioning::TargetAppInfo targetAppInfo;
targetAppInfo.vendorId = kDesiredEndpointVendorId;
Expand All @@ -418,8 +412,8 @@ CHIP_ERROR CommandHandler(int argc, char ** argv)
// This tv-app target Vendor ID (1111), does not implement the AccountLogin cluster, which would otherwise auto
// commission using the Commissionee-Generated passcode upon recieving the IdentificationDeclaration Message.
// See connectedhomeip/examples/tv-app/tv-common/include/AppTv.h.
targetAppInfo.vendorId = 1111;
gCommissionerGeneratedPasscodeFlow = true;
targetAppInfo.vendorId = 1111;
gCommissionerGeneratedPasscodeFlowRunning = true;
}
else
{
Expand Down
22 changes: 21 additions & 1 deletion examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace core {

CastingPlayer * CastingPlayer::mTargetCastingPlayer = nullptr;

void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCallbacks, uint64_t commissioningWindowTimeoutSec,
void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCallbacks, uint16_t commissioningWindowTimeoutSec,
IdentificationDeclarationOptions idOptions)
{
ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() called");
Expand Down Expand Up @@ -389,6 +389,26 @@ void CastingPlayer::LogDetail() const
}
}

CastingPlayer::CastingPlayer(const CastingPlayer & other) :
mEndpoints(other.mEndpoints), mConnectionState(other.mConnectionState), mAttributes(other.mAttributes),
mIdOptions(other.mIdOptions), mCommissioningWindowTimeoutSec(other.mCommissioningWindowTimeoutSec),
mOnCompleted(other.mOnCompleted)
{}

CastingPlayer & CastingPlayer::operator=(const CastingPlayer & other)
{
if (this != &other)
{
mAttributes = other.mAttributes;
mEndpoints = other.mEndpoints;
mConnectionState = other.mConnectionState;
mIdOptions = other.mIdOptions;
mCommissioningWindowTimeoutSec = other.mCommissioningWindowTimeoutSec;
mOnCompleted = other.mOnCompleted;
}
return *this;
}

ConnectionContext::ConnectionContext(void * clientContext, core::CastingPlayer * targetCastingPlayer,
chip::OnDeviceConnected onDeviceConnectedFn,
chip::OnDeviceConnectionFailure onDeviceConnectionFailureFn)
Expand Down
67 changes: 52 additions & 15 deletions examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace core {
const int kPortMaxLength = 5; // port is uint16_t
// +1 for the : between the hostname and the port.
const int kIdMaxLength = chip::Dnssd::kHostNameMaxLength + kPortMaxLength + 1;
const uint64_t kCommissioningWindowTimeoutSec = 3 * 60; // 3 minutes
const uint16_t kCommissioningWindowTimeoutSec = 3 * 60; // 3 minutes

/**
* @brief Describes an Endpoint that the client wants to connect to
Expand Down Expand Up @@ -111,41 +111,78 @@ class CastingPlayer : public std::enable_shared_from_this<CastingPlayer>
return (compareResult == 0) ? 1 : 0;
}

/**
* @brief Define the copy constructor
*/
CastingPlayer(const CastingPlayer & other);

/**
* @brief Define the assignment operator
*/
CastingPlayer & operator=(const CastingPlayer & other);

/**
* @return true if this CastingPlayer is connected to the CastingApp
*/
bool IsConnected() const { return mConnectionState == CASTING_PLAYER_CONNECTED; }

/**
* @brief Verifies that a connection exists with this CastingPlayer, or triggers a new session
* request. If the CastingApp does not have the nodeId and fabricIndex of this CastingPlayer cached on disk,
* this will execute the User Directed Commissioning (UDC) process.
* @brief Verifies that a connection exists with this CastingPlayer, or triggers a new commissioning session request. If the
* CastingApp does not have the nodeId and fabricIndex of this CastingPlayer cached on disk, this will execute the User Directed
* Commissioning (UDC) process by sending an IdentificationDeclaration message to the Commissioner. For certain UDC features,
* where a Commissioner reply is expected, this API needs to be followed up with the ContinueConnecting() API defiend below. See
* the Matter UDC specification or parameter class definitions for details on features not included in the description below.
*
* @param connectionCallbacks contains the ConnectCallback (Required) and CommissionerDeclarationCallback (Optional) defiend in
* ConnectCallbacks.h.
*
* ConnectCallback: The callback called when the connection process has ended, regardless of whether it was successful or not.
*
* CommissionerDeclarationCallback: The callback called when the Commissionee receives a CommissionerDeclaration message from
* the Commissioner. This callback is needed to support UDC features where a reply from the Commissioner is expected. It
* provides information indicating the Commissioner’s pre-commissioning state.
*
* For example: During Commissioner-Generated passcode commissioning, the Commissioner replies with a CommissionerDeclaration
* message with PasscodeDialogDisplayed and CommissionerPasscode set to true. Given these Commissioner state details, the client
* is expected to perform some actions, detailed in the ContinueConnecting() API below, and then call the ContinueConnecting()
* API to complete the process.
*
* @param connectionCallbacks contains the ConnectCallback and CommissionerDeclarationCallback (Optional).
* @param commissioningWindowTimeoutSec (Optional) time (in sec) to keep the commissioning window open, if commissioning is
* required. Needs to be >= kCommissioningWindowTimeoutSec.
*
* @param idOptions (Optional) Parameters in the IdentificationDeclaration message sent by the Commissionee to the Commissioner.
* These parameters specify the information relating to the requested commissioning session.
*
* For example: To invoke the Commissioner-Generated passcode commissioning flow, the client would call this API with
* IdentificationDeclarationOptions containing CommissionerPasscode set to true. See IdentificationDeclarationOptions.h for a
* complete list of optional parameters.
*
* Furthermore, attributes (such as VendorId) describe the TargetApp that the client wants to interact with after commissioning.
* If this value is passed in, VerifyOrEstablishConnection() will force UDC, in case the desired
* TargetApp is not found in the on-device CastingStore.
*/
void VerifyOrEstablishConnection(ConnectionCallbacks connectionCallbacks,
uint64_t commissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec,
uint16_t commissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec,
IdentificationDeclarationOptions idOptions = IdentificationDeclarationOptions());

/**
* @brief Continues the UDC process during the Commissioner-Generated passcode commissioning flow by sending a second
* IdentificationDeclaration to Commissioner containing CommissionerPasscode and CommissionerPasscodeReady set to true. At this
* point it is assumed that the following have occurred:
* 1. Client has handled the Commissioner's CommissionerDecelration message with PasscodeDialogDisplayed and
* CommissionerPasscode set to true.
* 2. Client prompted user to input Passcode from Commissioner.
* 3. Client has updated the commissioning session's PAKE verifier using the user input Passcode by updating the CastingApps
* @brief This is a continuation of the Commissioner-Generated passcode commissioning flow started via the
* VerifyOrEstablishConnection() API above. It continues the UDC process by sending a second IdentificationDeclaration message
* to Commissioner containing CommissionerPasscode and CommissionerPasscodeReady set to true. At this point it is assumed that
* the following have occurred:
*
* 1. Client (Commissionee) has sent the first IdentificationDeclaration message, via VerifyOrEstablishConnection(), to the
* Commissioner containing CommissionerPasscode set to true.
* 2. Commissioner generated and displayed a passcode.
* 3. The Commissioner replied with a CommissionerDecelration message with PasscodeDialogDisplayed and CommissionerPasscode set
* to true.
* 3. Client has handled the Commissioner's CommissionerDecelration message.
* 4. Client prompted user to input Passcode from Commissioner.
* 5. Client has updated the commissioning session's PAKE verifier using the user input Passcode by updating the CastingApps
* CommissionableDataProvider
* (matter::casting::core::CastingApp::GetInstance()->UpdateCommissionableDataProvider(CommissionableDataProvider)).
*
* The same connectionCallbacks and commissioningWindowTimeoutSec parameters passed in to VerifyOrEstablishConnection() will be
* The same connectionCallbacks and commissioningWindowTimeoutSec parameters passed into VerifyOrEstablishConnection() will be
* used.
*/
void ContinueConnecting();
Expand Down Expand Up @@ -218,7 +255,7 @@ class CastingPlayer : public std::enable_shared_from_this<CastingPlayer>
CastingPlayerAttributes mAttributes;
IdentificationDeclarationOptions mIdOptions;
static CastingPlayer * mTargetCastingPlayer;
uint64_t mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec;
uint16_t mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec;
ConnectCallback mOnCompleted = {};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ CommissionerDeclarationHandler * CommissionerDeclarationHandler::GetInstance()
}

// TODO: In the following PRs. Implement setHandler() for CommissionerDeclaration messages and expose messages to higher layers for
// Linux(DONE), Android(pending) and iOS(pending).
// Linux, Android and iOS.
void CommissionerDeclarationHandler::OnCommissionerDeclarationMessage(
const chip::Transport::PeerAddress & source, chip::Protocols::UserDirectedCommissioning::CommissionerDeclaration cd)
{
Expand Down
6 changes: 6 additions & 0 deletions examples/tv-casting-app/tv-casting-common/core/Endpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ class Endpoint : public std::enable_shared_from_this<Endpoint>
}
return nullptr;
}

void LogDetail() const
{
ChipLogProgress(AppServer, "Endpoint::LogDetail() Endpoint ID: %d, Vendor ID: %d, Product ID: %d", mAttributes.mId,
mAttributes.mVendorId, mAttributes.mProductId);
}
};

}; // namespace core
Expand Down

0 comments on commit 4918b5e

Please sign in to comment.