Skip to content

Commit a2ded0f

Browse files
Linux tv-casting-app v1.3 IdentificationDeclaration message (#33283)
1 parent 060143e commit a2ded0f

File tree

16 files changed

+368
-45
lines changed

16 files changed

+368
-45
lines changed

examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,9 @@ public View getView(int i, View view, ViewGroup viewGroup) {
327327
TAG,
328328
"OnClickListener.onClick() called for CastingPlayer with deviceId: "
329329
+ castingPlayer.getDeviceId());
330-
DiscoveryExampleFragment.Callback callback1 = (DiscoveryExampleFragment.Callback) context;
331-
callback1.handleConnectionButtonClicked(castingPlayer);
330+
DiscoveryExampleFragment.Callback onClickCallback =
331+
(DiscoveryExampleFragment.Callback) context;
332+
onClickCallback.handleConnectionButtonClicked(castingPlayer);
332333
};
333334
playerDescription.setOnClickListener(clickListener);
334335
return view;

examples/tv-casting-app/android/App/app/src/main/jni/cpp/core/MatterCastingPlayer-JNI.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,14 @@ JNI_METHOD(jobject, verifyOrEstablishConnection)
5353
CastingPlayer * castingPlayer = support::convertCastingPlayerFromJavaToCpp(thiz);
5454
VerifyOrReturnValue(castingPlayer != nullptr, support::convertMatterErrorFromCppToJava(CHIP_ERROR_INVALID_ARGUMENT));
5555

56+
matter::casting::core::IdentificationDeclarationOptions idOptions;
57+
58+
// TODO: In the following PRs. Replace EndpointFilter Java class with IdentificationDeclarationOptions Java class.
5659
matter::casting::core::EndpointFilter desiredEndpointFilter;
5760
if (desiredEndpointFilterJavaObject != nullptr)
5861
{
62+
chip::Protocols::UserDirectedCommissioning::TargetAppInfo targetAppInfo;
63+
5964
// Convert the EndpointFilter Java class to a C++ EndpointFilter
6065
jclass endpointFilterJavaClass = env->GetObjectClass(desiredEndpointFilterJavaObject);
6166
jfieldID vendorIdFieldId = env->GetFieldID(endpointFilterJavaClass, "vendorId", "Ljava/lang/Integer;");
@@ -66,20 +71,28 @@ JNI_METHOD(jobject, verifyOrEstablishConnection)
6671
// "Ljava/util/List;");
6772

6873
// Value of 0 means unspecified
69-
desiredEndpointFilter.vendorId = vendorIdIntegerObject != nullptr
74+
targetAppInfo.vendorId = vendorIdIntegerObject != nullptr
7075
? static_cast<uint16_t>(env->CallIntMethod(
7176
vendorIdIntegerObject, env->GetMethodID(env->GetObjectClass(vendorIdIntegerObject), "intValue", "()I")))
7277
: 0;
73-
desiredEndpointFilter.productId = productIdIntegerObject != nullptr
78+
targetAppInfo.productId = productIdIntegerObject != nullptr
7479
? static_cast<uint16_t>(env->CallIntMethod(
7580
productIdIntegerObject, env->GetMethodID(env->GetObjectClass(productIdIntegerObject), "intValue", "()I")))
7681
: 0;
77-
// TODO: In following PRs. Translate the Java requiredDeviceTypes list to a C++ requiredDeviceTypes vector. For now we're
78-
// passing an empty list of DeviceTypeStruct.
82+
83+
CHIP_ERROR result = idOptions.addTargetAppInfo(targetAppInfo);
84+
if (result != CHIP_NO_ERROR)
85+
{
86+
ChipLogError(AppServer,
87+
"MatterCastingPlayer-JNI::verifyOrEstablishConnection() failed to add targetAppInfo: %" CHIP_ERROR_FORMAT,
88+
result.Format());
89+
}
7990
}
8091

8192
MatterCastingPlayerJNIMgr().mConnectionSuccessHandler.SetUp(env, jSuccessCallback);
8293
MatterCastingPlayerJNIMgr().mConnectionFailureHandler.SetUp(env, jFailureCallback);
94+
95+
// TODO: In the following PRs. Add optional CommissionerDeclarationHandler callback parameter.
8396
castingPlayer->VerifyOrEstablishConnection(
8497
[](CHIP_ERROR err, CastingPlayer * playerPtr) {
8598
ChipLogProgress(AppServer, "MatterCastingPlayer-JNI::verifyOrEstablishConnection() ConnectCallback called");
@@ -96,7 +109,7 @@ JNI_METHOD(jobject, verifyOrEstablishConnection)
96109
MatterCastingPlayerJNIMgr().mConnectionFailureHandler.Handle(err);
97110
}
98111
},
99-
static_cast<unsigned long long int>(commissioningWindowTimeoutSec), desiredEndpointFilter);
112+
static_cast<unsigned long long int>(commissioningWindowTimeoutSec), idOptions);
100113
return support::convertMatterErrorFromCppToJava(CHIP_NO_ERROR);
101114
}
102115

examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MCCastingPlayer.mm

+13-3
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,29 @@ - (void)verifyOrEstablishConnectionWithCompletionBlock:(void (^_Nonnull)(NSError
5252

5353
dispatch_queue_t workQueue = [[MCCastingApp getSharedInstance] getWorkQueue];
5454
dispatch_sync(workQueue, ^{
55+
matter::casting::core::IdentificationDeclarationOptions idOptions;
56+
57+
// TODO: In the following PRs. Replace EndpointFilter objC class with IdentificationDeclarationOptions objC class.
5558
__block matter::casting::core::EndpointFilter cppDesiredEndpointFilter;
5659
if (desiredEndpointFilter != nil) {
57-
cppDesiredEndpointFilter.vendorId = desiredEndpointFilter.vendorId;
58-
cppDesiredEndpointFilter.productId = desiredEndpointFilter.productId;
60+
chip::Protocols::UserDirectedCommissioning::TargetAppInfo targetAppInfo;
61+
targetAppInfo.vendorId = desiredEndpointFilter.vendorId;
62+
targetAppInfo.productId = desiredEndpointFilter.productId;
63+
64+
CHIP_ERROR result = idOptions.addTargetAppInfo(targetAppInfo);
65+
if (result != CHIP_NO_ERROR) {
66+
ChipLogError(AppServer, "MCCastingPlayer.verifyOrEstablishConnectionWithCompletionBlock failed to add targetAppInfo: %" CHIP_ERROR_FORMAT, result.Format());
67+
}
5968
}
6069

70+
// TODO: In the following PRs. Add optional CommissionerDeclarationHandler callback parameter.
6171
_cppCastingPlayer->VerifyOrEstablishConnection(
6272
[completion](CHIP_ERROR err, matter::casting::core::CastingPlayer * castingPlayer) {
6373
dispatch_queue_t clientQueue = [[MCCastingApp getSharedInstance] getClientQueue];
6474
dispatch_async(clientQueue, ^{
6575
completion(err == CHIP_NO_ERROR ? nil : [MCErrorUtils NSErrorFromChipError:err]);
6676
});
67-
}, timeout, cppDesiredEndpointFilter);
77+
}, timeout, idOptions);
6878
});
6979
}
7080

examples/tv-casting-app/linux/simple-app-helper.cpp

+49-11
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ void DiscoveryDelegateImpl::HandleOnAdded(matter::casting::memory::Strong<matter
4949
if (commissionersCount == 0)
5050
{
5151
ChipLogProgress(AppServer, "Select discovered Casting Player (start index = 0) to request commissioning");
52+
ChipLogProgress(AppServer, "Include the cgp flag to attempt the Commissioner-Generated Passcode commissioning flow");
5253

53-
ChipLogProgress(AppServer, "Example: cast request 0");
54+
ChipLogProgress(AppServer, "Example1 Commissionee Passcode: cast request 0");
55+
ChipLogProgress(AppServer, "Example2 Commissioner Passcode: cast request 0 cgp");
5456
}
5557
ChipLogProgress(AppServer, "Discovered CastingPlayer #%d", commissionersCount);
5658
++commissionersCount;
@@ -170,10 +172,12 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca
170172
{
171173
VerifyOrReturn(err == CHIP_NO_ERROR,
172174
ChipLogProgress(AppServer,
173-
"ConnectionHandler: Failed to connect to CastingPlayer(ID: %s) with err %" CHIP_ERROR_FORMAT,
175+
"ConnectionHandler(): Failed to connect to CastingPlayer(ID: %s) with err %" CHIP_ERROR_FORMAT,
174176
castingPlayer->GetId(), err.Format()));
175177

176-
ChipLogProgress(AppServer, "ConnectionHandler: Successfully connected to CastingPlayer(ID: %s)", castingPlayer->GetId());
178+
ChipLogProgress(AppServer, "ConnectionHandler(): Successfully connected to CastingPlayer(ID: %s)", castingPlayer->GetId());
179+
ChipLogProgress(AppServer, "ConnectionHandler(): Triggering demo interactions with CastingPlayer(ID: %s)",
180+
castingPlayer->GetId());
177181

178182
std::vector<matter::casting::memory::Strong<matter::casting::core::Endpoint>> endpoints = castingPlayer->GetEndpoints();
179183
// Find the desired Endpoint and auto-trigger some Matter Casting demo interactions
@@ -219,18 +223,18 @@ CHIP_ERROR CommandHandler(int argc, char ** argv)
219223
}
220224
if (strcmp(argv[0], "discover") == 0)
221225
{
222-
ChipLogProgress(AppServer, "discover");
226+
ChipLogProgress(AppServer, "CommandHandler() discover");
223227

224228
return matter::casting::core::CastingPlayerDiscovery::GetInstance()->StartDiscovery(kTargetPlayerDeviceType);
225229
}
226230
if (strcmp(argv[0], "stop-discovery") == 0)
227231
{
228-
ChipLogProgress(AppServer, "stop-discovery");
232+
ChipLogProgress(AppServer, "CommandHandler() stop-discovery");
229233
return matter::casting::core::CastingPlayerDiscovery::GetInstance()->StopDiscovery();
230234
}
231235
if (strcmp(argv[0], "request") == 0)
232236
{
233-
ChipLogProgress(AppServer, "request");
237+
ChipLogProgress(AppServer, "CommandHandler() request");
234238
if (argc < 2)
235239
{
236240
return PrintAllCommands();
@@ -243,10 +247,40 @@ CHIP_ERROR CommandHandler(int argc, char ** argv)
243247
ChipLogError(AppServer, "Invalid casting player index provided: %lu", index));
244248
std::shared_ptr<matter::casting::core::CastingPlayer> targetCastingPlayer = castingPlayers.at(index);
245249

246-
matter::casting::core::EndpointFilter desiredEndpointFilter;
247-
desiredEndpointFilter.vendorId = kDesiredEndpointVendorId;
250+
matter::casting::core::IdentificationDeclarationOptions idOptions;
251+
if (argc == 3)
252+
{
253+
if (strcmp(argv[2], "cgp") == 0)
254+
{
255+
// Attempt Commissioner-Generated Passcode (cgp) commissioning flow only if the CastingPlayer indicates support for
256+
// it.
257+
if (targetCastingPlayer->GetSupportsCommissionerGeneratedPasscode())
258+
{
259+
ChipLogProgress(
260+
AppServer,
261+
"CommandHandler() request %lu cgp. Attempting the Commissioner-Generated Passcode commissioning flow",
262+
index);
263+
idOptions.mCommissionerPasscode = true;
264+
}
265+
else
266+
{
267+
ChipLogError(AppServer,
268+
"CommandHandler() request %lu cgp. Selected CastingPLayer does not support the "
269+
"Commissioner-Generated Passcode commissioning flow",
270+
index);
271+
}
272+
}
273+
}
274+
chip::Protocols::UserDirectedCommissioning::TargetAppInfo targetAppInfo;
275+
targetAppInfo.vendorId = kDesiredEndpointVendorId;
276+
CHIP_ERROR result = idOptions.addTargetAppInfo(targetAppInfo);
277+
if (result != CHIP_NO_ERROR)
278+
{
279+
ChipLogError(AppServer, "CommandHandler() request, failed to add targetAppInfo: %" CHIP_ERROR_FORMAT, result.Format());
280+
}
281+
248282
targetCastingPlayer->VerifyOrEstablishConnection(ConnectionHandler, matter::casting::core::kCommissioningWindowTimeoutSec,
249-
desiredEndpointFilter);
283+
idOptions);
250284
return CHIP_NO_ERROR;
251285
}
252286
if (strcmp(argv[0], "print-bindings") == 0)
@@ -280,8 +314,12 @@ CHIP_ERROR PrintAllCommands()
280314
" delete-fabric <index> Delete a fabric from the casting client's fabric store. Usage: cast delete-fabric 1\r\n");
281315
streamer_printf(sout, " discover Discover Casting Players. Usage: cast discover\r\n");
282316
streamer_printf(sout, " stop-discovery Stop Discovery of Casting Players. Usage: cast stop-discovery\r\n");
283-
streamer_printf(
284-
sout, " request <index> Request connecting to discovered Casting Player with [index]. Usage: cast request 0\r\n");
317+
streamer_printf(sout,
318+
" request <index> Request connecting to discovered Casting Player with [index] using the "
319+
"Commissionee-Generated Passcode commissioning flow. Usage: cast request 0\r\n");
320+
streamer_printf(sout,
321+
" request <index> cgp Request connecting to discovered Casting Player with [index] using the "
322+
"Commissioner-Generated Passcode commissioning flow. Usage: cast request 0 cgp\r\n");
285323
streamer_printf(sout, "\r\n");
286324

287325
return CHIP_NO_ERROR;

examples/tv-casting-app/linux/simple-app-helper.h

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "core/CastingPlayer.h"
2222
#include "core/CastingPlayerDiscovery.h"
23+
#include "core/IdentificationDeclarationOptions.h"
2324
#include "core/Types.h"
2425
#include <platform/CHIPDeviceLayer.h>
2526

examples/tv-casting-app/tv-casting-common/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ chip_data_model("tv-casting-common") {
106106
"core/CastingPlayerDiscovery.cpp",
107107
"core/CastingPlayerDiscovery.h",
108108
"core/Command.h",
109+
"core/CommissionerDeclarationHandler.cpp",
109110
"core/Endpoint.cpp",
110111
"core/Endpoint.h",
111112
"core/Types.h",

examples/tv-casting-app/tv-casting-common/core/CastingApp.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "CastingApp.h"
2020

21+
#include "CommissionerDeclarationHandler.h"
2122
#include "support/CastingStore.h"
2223
#include "support/ChipDeviceEventHandler.h"
2324

@@ -100,6 +101,9 @@ CHIP_ERROR CastingApp::Start()
100101
// reconnect (or verify connection) to the CastingPlayer that the app was connected to before being stopped, if any
101102
if (CastingPlayer::GetTargetCastingPlayer() != nullptr)
102103
{
104+
ChipLogProgress(
105+
Discovery,
106+
"CastingApp::Start() calling VerifyOrEstablishConnection() to reconnect (or verify connection) to a CastingPlayer");
103107
CastingPlayer::GetTargetCastingPlayer()->VerifyOrEstablishConnection(
104108
[](CHIP_ERROR err, matter::casting::core::CastingPlayer * castingPlayer) {
105109
if (err != CHIP_NO_ERROR)
@@ -136,6 +140,12 @@ CHIP_ERROR CastingApp::PostStartRegistrations()
136140
// Register DeviceEvent Handler
137141
ReturnErrorOnFailure(chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(ChipDeviceEventHandler::Handle, 0));
138142

143+
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
144+
// Set a handler for Commissioner's CommissionerDeclaration messages.
145+
chip::Server::GetInstance().GetUserDirectedCommissioningClient()->SetCommissionerDeclarationHandler(
146+
CommissionerDeclarationHandler::GetInstance());
147+
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
148+
139149
mState = CASTING_APP_RUNNING; // CastingApp started successfully, set state to RUNNING
140150
return CHIP_NO_ERROR;
141151
}
@@ -145,6 +155,11 @@ CHIP_ERROR CastingApp::Stop()
145155
ChipLogProgress(Discovery, "CastingApp::Stop() called");
146156
VerifyOrReturnError(mState == CASTING_APP_RUNNING, CHIP_ERROR_INCORRECT_STATE);
147157

158+
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
159+
// Remove the handler previously set for Commissioner's CommissionerDeclaration messages.
160+
chip::Server::GetInstance().GetUserDirectedCommissioningClient()->SetCommissionerDeclarationHandler(nullptr);
161+
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
162+
148163
// Shutdown the Matter server
149164
chip::Server::GetInstance().Shutdown();
150165

examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp

+23-14
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace core {
3030
CastingPlayer * CastingPlayer::mTargetCastingPlayer = nullptr;
3131

3232
void CastingPlayer::VerifyOrEstablishConnection(ConnectCallback onCompleted, unsigned long long int commissioningWindowTimeoutSec,
33-
EndpointFilter desiredEndpointFilter)
33+
IdentificationDeclarationOptions idOptions)
3434
{
3535
ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() called");
3636

@@ -50,20 +50,22 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectCallback onCompleted, uns
5050
mOnCompleted = onCompleted;
5151
mCommissioningWindowTimeoutSec = commissioningWindowTimeoutSec;
5252
mTargetCastingPlayer = this;
53+
mIdOptions = idOptions;
5354

5455
// If *this* CastingPlayer was previously connected to, its nodeId, fabricIndex and other attributes should be present
5556
// in the CastingStore cache. If that is the case, AND, the cached data contains the endpoint desired by the client, if any,
56-
// as per desiredEndpointFilter, simply Find or Re-establish the CASE session and return early
57+
// as per IdentificationDeclarationOptions.mTargetAppInfos, simply Find or Re-establish the CASE session and return early.
5758
if (cachedCastingPlayers.size() != 0)
5859
{
60+
ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() Re-establishing CASE with cached CastingPlayer");
5961
it = std::find_if(cachedCastingPlayers.begin(), cachedCastingPlayers.end(),
6062
[this](const core::CastingPlayer & castingPlayerParam) { return castingPlayerParam == *this; });
6163

6264
// found the CastingPlayer in cache
6365
if (it != cachedCastingPlayers.end())
6466
{
6567
unsigned index = (unsigned int) std::distance(cachedCastingPlayers.begin(), it);
66-
if (ContainsDesiredEndpoint(&cachedCastingPlayers[index], desiredEndpointFilter))
68+
if (ContainsDesiredTargetApp(&cachedCastingPlayers[index], idOptions.getTargetAppInfoList()))
6769
{
6870
ChipLogProgress(
6971
AppServer,
@@ -163,14 +165,15 @@ void CastingPlayer::RegisterEndpoint(const memory::Strong<Endpoint> endpoint)
163165
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
164166
CHIP_ERROR CastingPlayer::SendUserDirectedCommissioningRequest()
165167
{
168+
ChipLogProgress(AppServer, "CastingPlayer::SendUserDirectedCommissioningRequest()");
166169
chip::Inet::IPAddress * ipAddressToUse = GetIpAddressForUDCRequest();
167170
VerifyOrReturnValue(ipAddressToUse != nullptr, CHIP_ERROR_INCORRECT_STATE,
168171
ChipLogError(AppServer, "No IP Address found to send UDC request to"));
169172

170173
ReturnErrorOnFailure(support::ChipDeviceEventHandler::SetUdcStatus(true));
171174

172-
// TODO: expose options to the higher layer
173-
chip::Protocols::UserDirectedCommissioning::IdentificationDeclaration id;
175+
chip::Protocols::UserDirectedCommissioning::IdentificationDeclaration id = mIdOptions.buildIdentificationDeclarationMessage();
176+
174177
ReturnErrorOnFailure(chip::Server::GetInstance().SendUserDirectedCommissioningRequest(
175178
chip::Transport::PeerAddress::UDP(*ipAddressToUse, mAttributes.port, mAttributes.interfaceId), id));
176179

@@ -216,21 +219,27 @@ void CastingPlayer::FindOrEstablishSession(void * clientContext, chip::OnDeviceC
216219
connectionContext->mOnConnectionFailureCallback);
217220
}
218221

219-
bool CastingPlayer::ContainsDesiredEndpoint(core::CastingPlayer * cachedCastingPlayer, EndpointFilter desiredEndpointFilter)
222+
bool CastingPlayer::ContainsDesiredTargetApp(
223+
core::CastingPlayer * cachedCastingPlayer,
224+
std::vector<chip::Protocols::UserDirectedCommissioning::TargetAppInfo> desiredTargetApps)
220225
{
221226
std::vector<memory::Strong<Endpoint>> cachedEndpoints = cachedCastingPlayer->GetEndpoints();
222-
for (const auto & cachedEndpoint : cachedEndpoints)
227+
for (size_t i = 0; i < desiredTargetApps.size(); i++)
223228
{
224-
bool match = true;
225-
match = match && (desiredEndpointFilter.vendorId == 0 || cachedEndpoint->GetVendorId() == desiredEndpointFilter.vendorId);
226-
match =
227-
match && (desiredEndpointFilter.productId == 0 || cachedEndpoint->GetProductId() == desiredEndpointFilter.productId);
228-
// TODO: check deviceTypeList
229-
if (match)
229+
for (const auto & cachedEndpoint : cachedEndpoints)
230230
{
231-
return true;
231+
bool match = true;
232+
match = match && (desiredTargetApps[i].vendorId == 0 || cachedEndpoint->GetVendorId() == desiredTargetApps[i].vendorId);
233+
match =
234+
match && (desiredTargetApps[i].productId == 0 || cachedEndpoint->GetProductId() == desiredTargetApps[i].productId);
235+
if (match)
236+
{
237+
ChipLogProgress(AppServer, "CastingPlayer::ContainsDesiredTargetApp() matching cached CastingPlayer found");
238+
return true;
239+
}
232240
}
233241
}
242+
ChipLogProgress(AppServer, "CastingPlayer::ContainsDesiredTargetApp() matching cached CastingPlayer not found");
234243
return false;
235244
}
236245

0 commit comments

Comments
 (0)