Skip to content

Commit 5258814

Browse files
sharadb-amazonpull[bot]
authored andcommitted
Fixes in tv-casting-app to allow setting custom Setup Passcodes and backgrounding the app on iOS (#24046)
* tv-casting-app: Making getDiscoveredCommissioner API synchronous * iOS MatterTvCastingBridge: Generate spake2pSalt (and verifier) if required in CommissionableDataProviderImpl * tv-casting-app/darwin: Stopping/restarting Matter server when app becomes inactive/active. Also, disabling BLE * Addressing cliffamzn@'s feedback
1 parent 8739d86 commit 5258814

File tree

10 files changed

+405
-176
lines changed

10 files changed

+405
-176
lines changed

examples/tv-casting-app/android/args.gni

+2
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ chip_build_libshell = true
2929
chip_enable_additional_data_advertising = true
3030

3131
chip_enable_rotating_device_id = true
32+
33+
chip_config_network_layer_ble = false

examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
3CCB8742286A593700771BAD /* ConversionUtils.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB873C286A593700771BAD /* ConversionUtils.hpp */; };
2727
3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873D286A593700771BAD /* CastingServerBridge.mm */; };
2828
3CCB8744286A593700771BAD /* ConversionUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873E286A593700771BAD /* ConversionUtils.mm */; };
29+
3CE868F42946D76200FCB92B /* CommissionableDataProviderImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CE868F32946D76200FCB92B /* CommissionableDataProviderImpl.mm */; };
2930
3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF8532628E37F1000F07B9F /* MatterError.mm */; };
3031
/* End PBXBuildFile section */
3132

@@ -59,6 +60,7 @@
5960
3CCB873C286A593700771BAD /* ConversionUtils.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ConversionUtils.hpp; sourceTree = "<group>"; };
6061
3CCB873D286A593700771BAD /* CastingServerBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CastingServerBridge.mm; sourceTree = "<group>"; };
6162
3CCB873E286A593700771BAD /* ConversionUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConversionUtils.mm; sourceTree = "<group>"; };
63+
3CE868F32946D76200FCB92B /* CommissionableDataProviderImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CommissionableDataProviderImpl.mm; sourceTree = "<group>"; };
6264
3CF8532528E37ED800F07B9F /* MatterError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MatterError.h; sourceTree = "<group>"; };
6365
3CF8532628E37F1000F07B9F /* MatterError.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MatterError.mm; sourceTree = "<group>"; };
6466
/* End PBXFileReference section */
@@ -125,6 +127,7 @@
125127
3C26AC8B2926FE0C00BA6881 /* DeviceAttestationCredentialsProviderImpl.hpp */,
126128
3C26AC8F2927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm */,
127129
3C0D9CDF2920A30C00D3332B /* CommissionableDataProviderImpl.hpp */,
130+
3CE868F32946D76200FCB92B /* CommissionableDataProviderImpl.mm */,
128131
);
129132
path = MatterTvCastingBridge;
130133
sourceTree = "<group>";
@@ -241,6 +244,7 @@
241244
3CCB8744286A593700771BAD /* ConversionUtils.mm in Sources */,
242245
3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */,
243246
3C66FBFC290327BB00B63FE7 /* AppParameters.mm in Sources */,
247+
3CE868F42946D76200FCB92B /* CommissionableDataProviderImpl.mm in Sources */,
244248
3C26AC9329282B8100BA6881 /* DeviceAttestationCredentialsHolder.m in Sources */,
245249
3C26AC902927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm in Sources */,
246250
3CCB873F286A593700771BAD /* DiscoveredNodeData.mm in Sources */,

examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/AppParameters.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131

3232
@property uint32_t spake2pIterationCount;
3333

34-
@property NSData * spake2pSalt;
34+
@property NSData * spake2pSaltBase64;
3535

36-
@property NSData * spake2pVerifier;
36+
@property NSData * spake2pVerifierBase64;
3737

3838
@property DeviceAttestationCredentialsHolder * deviceAttestationCredentials;
3939

examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
5555
@param clientQueue Queue to dispatch the call to the discoveredCommissionerHandler on
5656
57-
@param discoveredCommissionerHandler Handler to call after a discovered commissioner has been retrieved
57+
@param discoveredCommissionerHandler Handler called synchronously after a discovered commissioner has been retrieved
5858
*/
5959
- (void)getDiscoveredCommissioner:(int)index
6060
clientQueue:(dispatch_queue_t _Nonnull)clientQueue
@@ -184,6 +184,16 @@
184184
*/
185185
- (void)disconnect:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(nullable void (^)())requestSentHandler;
186186

187+
/**
188+
@brief Start the Matter server and reconnect to a previously connected Video Player (if any)
189+
*/
190+
- (void)startMatterServer;
191+
192+
/**
193+
@brief Stop the Matter server
194+
*/
195+
- (void)stopMatterServer;
196+
187197
/*!
188198
@brief Send a ContentLauncher:LaunchURL request to a TV
189199

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

+112-24
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ @interface CastingServerBridge ()
3838

3939
@property OnboardingPayload * _Nonnull onboardingPayload;
4040

41-
@property chip::DeviceLayer::CommissionableDataProviderImpl * commissionableDataProvider;
41+
@property CommissionableDataProviderImpl * commissionableDataProvider;
4242

4343
@property chip::Credentials::DeviceAttestationCredentialsProvider * deviceAttestationCredentialsProvider;
4444

45+
@property chip::CommonCaseDeviceServerInitParams * serverInitParams;
46+
47+
@property TargetVideoPlayerInfo * previouslyConnectedVideoPlayer;
48+
4549
// queue used to serialize all work performed by the CastingServerBridge
4650
@property (atomic) dispatch_queue_t chipWorkQueue;
4751

@@ -111,10 +115,15 @@ - (void)initApp:(AppParameters * _Nullable)appParameters
111115
ChipLogProgress(AppServer, "CastingServerBridge().initApp() called");
112116

113117
CHIP_ERROR err = CHIP_NO_ERROR;
114-
_commissionableDataProvider = new chip::DeviceLayer::CommissionableDataProviderImpl();
118+
_commissionableDataProvider = new CommissionableDataProviderImpl();
115119
_deviceAttestationCredentialsProvider = chip::Credentials::Examples::GetExampleDACProvider();
120+
116121
_appParameters = appParameters;
117122
AppParams cppAppParams;
123+
uint32_t setupPasscode = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE;
124+
uint16_t setupDiscriminator = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR;
125+
uint32_t spake2pIterationCount;
126+
chip::ByteSpan spake2pSaltSpan, spake2pVerifierSpan;
118127
if (_appParameters != nil) {
119128
err = [ConversionUtils convertToCppAppParamsInfoFrom:_appParameters outAppParams:cppAppParams];
120129
if (err != CHIP_NO_ERROR) {
@@ -123,22 +132,31 @@ - (void)initApp:(AppParameters * _Nullable)appParameters
123132
}
124133

125134
// set fields in commissionableDataProvider
126-
_commissionableDataProvider->SetSpake2pIterationCount(_appParameters.spake2pIterationCount);
127-
if (_appParameters.spake2pSalt != nil) {
128-
chip::ByteSpan spake2pSaltSpan
129-
= chip::ByteSpan(static_cast<const uint8_t *>(_appParameters.spake2pSalt.bytes), _appParameters.spake2pSalt.length);
130-
_commissionableDataProvider->SetSpake2pSalt(spake2pSaltSpan);
135+
if (_appParameters.onboardingPayload != nil) {
136+
setupPasscode = _appParameters.onboardingPayload.setupPasscode > 0 ? _appParameters.onboardingPayload.setupPasscode
137+
: CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE;
138+
setupDiscriminator = _appParameters.onboardingPayload.setupDiscriminator > 0
139+
? _appParameters.onboardingPayload.setupDiscriminator
140+
: CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR;
141+
}
142+
spake2pIterationCount = _appParameters.spake2pIterationCount;
143+
if (_appParameters.spake2pSaltBase64 != nil) {
144+
spake2pSaltSpan = chip::ByteSpan(
145+
static_cast<const uint8_t *>(_appParameters.spake2pSaltBase64.bytes), _appParameters.spake2pSaltBase64.length);
131146
}
132147

133-
if (_appParameters.spake2pVerifier != nil) {
134-
chip::ByteSpan spake2pVerifierSpan = chip::ByteSpan(
135-
static_cast<const uint8_t *>(_appParameters.spake2pVerifier.bytes), _appParameters.spake2pVerifier.length);
136-
_commissionableDataProvider->SetSpake2pSalt(spake2pVerifierSpan);
148+
if (_appParameters.spake2pVerifierBase64 != nil) {
149+
chip::ByteSpan spake2pVerifierSpan
150+
= chip::ByteSpan(static_cast<const uint8_t *>(_appParameters.spake2pVerifierBase64.bytes),
151+
_appParameters.spake2pVerifierBase64.length);
137152
}
138153

139-
if (_appParameters.onboardingPayload != nil) {
140-
_commissionableDataProvider->SetSetupPasscode(_appParameters.onboardingPayload.setupPasscode);
141-
_commissionableDataProvider->SetSetupDiscriminator(_appParameters.onboardingPayload.setupDiscriminator);
154+
err = _commissionableDataProvider->Initialize(_appParameters.spake2pVerifierBase64 != nil ? &spake2pVerifierSpan : nil,
155+
_appParameters.spake2pSaltBase64 != nil ? &spake2pSaltSpan : nil, spake2pIterationCount, setupPasscode,
156+
setupDiscriminator);
157+
if (err != CHIP_NO_ERROR) {
158+
ChipLogError(AppServer, "Failed to initialize CommissionableDataProvider: %s", ErrorStr(err));
159+
return;
142160
}
143161

144162
if (_appParameters.deviceAttestationCredentials != nil) {
@@ -182,8 +200,6 @@ - (void)initApp:(AppParameters * _Nullable)appParameters
182200
}
183201
chip::DeviceLayer::SetCommissionableDataProvider(_commissionableDataProvider);
184202

185-
uint32_t setupPasscode = 0;
186-
uint16_t setupDiscriminator = 0;
187203
_commissionableDataProvider->GetSetupPasscode(setupPasscode);
188204
_commissionableDataProvider->GetSetupDiscriminator(setupDiscriminator);
189205
_onboardingPayload = [[OnboardingPayload alloc] initWithSetupPasscode:setupPasscode setupDiscriminator:setupDiscriminator];
@@ -199,14 +215,14 @@ - (void)initApp:(AppParameters * _Nullable)appParameters
199215
}
200216

201217
// init app Server
202-
static chip::CommonCaseDeviceServerInitParams initParams;
203-
err = initParams.InitializeStaticResourcesBeforeServerInit();
218+
_serverInitParams = new chip::CommonCaseDeviceServerInitParams();
219+
err = _serverInitParams->InitializeStaticResourcesBeforeServerInit();
204220
if (err != CHIP_NO_ERROR) {
205221
ChipLogError(AppServer, "InitializeStaticResourcesBeforeServerInit failed: %s", ErrorStr(err));
206222
return;
207223
}
208224

209-
err = chip::Server::GetInstance().Init(initParams);
225+
err = chip::Server::GetInstance().Init(*_serverInitParams);
210226
if (err != CHIP_NO_ERROR) {
211227
ChipLogError(AppServer, "chip::Server init failed: %s", ErrorStr(err));
212228
return;
@@ -261,7 +277,7 @@ - (void)getDiscoveredCommissioner:(int)index
261277
{
262278
ChipLogProgress(AppServer, "CastingServerBridge().getDiscoveredCommissioner() called");
263279

264-
dispatch_async(_chipWorkQueue, ^{
280+
dispatch_sync(_chipWorkQueue, ^{
265281
chip::Optional<TargetVideoPlayerInfo *> associatedConnectableVideoPlayer;
266282
DiscoveredNodeData * commissioner = nil;
267283
const chip::Dnssd::DiscoveredNodeData * cppDiscoveredNodeData
@@ -275,7 +291,7 @@ - (void)getDiscoveredCommissioner:(int)index
275291
}
276292
}
277293

278-
dispatch_async(clientQueue, ^{
294+
dispatch_sync(clientQueue, ^{
279295
discoveredCommissionerHandler(commissioner);
280296
});
281297
});
@@ -407,10 +423,9 @@ - (void)getActiveTargetVideoPlayers:(dispatch_queue_t _Nonnull)clientQueue
407423
ChipLogProgress(AppServer, "CastingServerBridge().getActiveTargetVideoPlayers() called");
408424

409425
dispatch_async(_chipWorkQueue, ^{
410-
NSMutableArray * videoPlayers = nil;
426+
NSMutableArray * videoPlayers = [NSMutableArray new];
411427
TargetVideoPlayerInfo * cppTargetVideoPlayerInfo = CastingServer::GetInstance()->GetActiveTargetVideoPlayer();
412-
if (cppTargetVideoPlayerInfo != nullptr) {
413-
videoPlayers = [NSMutableArray new];
428+
if (cppTargetVideoPlayerInfo != nullptr && cppTargetVideoPlayerInfo->IsInitialized()) {
414429
videoPlayers[0] = [ConversionUtils convertToObjCVideoPlayerFrom:cppTargetVideoPlayerInfo];
415430
}
416431

@@ -495,6 +510,79 @@ - (void)shutdownAllSubscriptions:(dispatch_queue_t _Nonnull)clientQueue requestS
495510
});
496511
}
497512

513+
- (void)startMatterServer
514+
{
515+
ChipLogProgress(AppServer, "CastingServerBridge().startMatterServer() called");
516+
517+
dispatch_sync(_chipWorkQueue, ^{
518+
// Initialize the Matter server
519+
CHIP_ERROR err = chip::Server::GetInstance().Init(*self->_serverInitParams);
520+
if (err != CHIP_NO_ERROR) {
521+
ChipLogError(AppServer, "chip::Server init failed: %s", ErrorStr(err));
522+
return;
523+
}
524+
525+
// Now reconnect to the VideoPlayer the casting app was previously connected to (if any)
526+
if (self->_previouslyConnectedVideoPlayer != nil) {
527+
ChipLogProgress(
528+
AppServer, "CastingServerBridge().startMatterServer() reconnecting to previously connected VideoPlayer...");
529+
err = CastingServer::GetInstance()->VerifyOrEstablishConnection(
530+
*(self->_previouslyConnectedVideoPlayer), [](TargetVideoPlayerInfo * cppTargetVideoPlayerInfo) {},
531+
[](CHIP_ERROR err) {}, [](TargetEndpointInfo * cppTargetEndpointInfo) {});
532+
}
533+
});
534+
}
535+
536+
- (void)stopMatterServer
537+
{
538+
ChipLogProgress(AppServer, "CastingServerBridge().stopMatterServer() called");
539+
540+
dispatch_sync(_chipWorkQueue, ^{
541+
// capture pointer to previouslyConnectedVideoPlayer, to be deleted
542+
TargetVideoPlayerInfo * videoPlayerForDeletion
543+
= self->_previouslyConnectedVideoPlayer == nil ? nil : self->_previouslyConnectedVideoPlayer;
544+
545+
// On shutting down the Matter server, the casting app will be automatically disconnected from any Video Players it was
546+
// connected to. Save the VideoPlayer that the casting app was targetting and connected to, so we can reconnect to it on
547+
// re-starting the Matter server.
548+
TargetVideoPlayerInfo * currentTargetVideoPlayerInfo = CastingServer::GetInstance()->GetActiveTargetVideoPlayer();
549+
if (currentTargetVideoPlayerInfo != nil && currentTargetVideoPlayerInfo->IsInitialized()
550+
&& currentTargetVideoPlayerInfo->GetOperationalDeviceProxy() != nil) {
551+
self->_previouslyConnectedVideoPlayer = new TargetVideoPlayerInfo();
552+
self->_previouslyConnectedVideoPlayer->Initialize(currentTargetVideoPlayerInfo->GetNodeId(),
553+
currentTargetVideoPlayerInfo->GetFabricIndex(), nullptr, nullptr, currentTargetVideoPlayerInfo->GetVendorId(),
554+
currentTargetVideoPlayerInfo->GetProductId(), currentTargetVideoPlayerInfo->GetDeviceType(),
555+
currentTargetVideoPlayerInfo->GetDeviceName(), currentTargetVideoPlayerInfo->GetNumIPs(),
556+
const_cast<chip::Inet::IPAddress *>(currentTargetVideoPlayerInfo->GetIpAddresses()));
557+
558+
TargetEndpointInfo * prevEndpoints = self->_previouslyConnectedVideoPlayer->GetEndpoints();
559+
if (prevEndpoints != nullptr) {
560+
for (size_t i = 0; i < kMaxNumberOfEndpoints; i++) {
561+
prevEndpoints[i].Reset();
562+
}
563+
}
564+
TargetEndpointInfo * currentEndpoints = currentTargetVideoPlayerInfo->GetEndpoints();
565+
for (size_t i = 0; i < kMaxNumberOfEndpoints && currentEndpoints[i].IsInitialized(); i++) {
566+
prevEndpoints[i].Initialize(currentEndpoints[i].GetEndpointId());
567+
chip::ClusterId * currentClusters = currentEndpoints[i].GetClusters();
568+
for (size_t j = 0; j < kMaxNumberOfClustersPerEndpoint && currentClusters[j] != chip::kInvalidClusterId; j++) {
569+
prevEndpoints[i].AddCluster(currentClusters[j]);
570+
}
571+
}
572+
} else {
573+
self->_previouslyConnectedVideoPlayer = nil;
574+
}
575+
576+
// Now shutdown the Matter server
577+
chip::Server::GetInstance().Shutdown();
578+
579+
// Delete the old previouslyConnectedVideoPlayer, if non-nil
580+
if (videoPlayerForDeletion != nil) {
581+
delete videoPlayerForDeletion;
582+
}
583+
});
584+
}
585+
498586
- (void)disconnect:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(nullable void (^)())requestSentHandler
499587
{
500588
ChipLogProgress(AppServer, "CastingServerBridge().disconnect() called");

0 commit comments

Comments
 (0)