Skip to content

Commit

Permalink
examples/tv-casting-app: Allow setting DACCredentials on iOS and add …
Browse files Browse the repository at this point in the history
…retry mechanism for commissioner discovery (project-chip#23692)

* MatterTvCastingBridge.Framework: Add a way to provide DAC creds

* Android tv-casting lib: Implementing a retry mechanism for commissioner service resolution using NsdManager
  • Loading branch information
sharadb-amazon committed Nov 28, 2022
1 parent 0e944dc commit 53a4db1
Show file tree
Hide file tree
Showing 11 changed files with 456 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ public void handle(MatterError matterError) {
}
};

Button discoverButton = getView().findViewById(R.id.discoverButton);
discoverButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Discovering on button click");
tvCastingApp.discoverVideoPlayerCommissioners(
DISCOVERY_DURATION_SECS, successCallback, failureCallback);
}
});

Log.d(TAG, "Auto discovering");
tvCastingApp.discoverVideoPlayerCommissioners(
DISCOVERY_DURATION_SECS, successCallback, failureCallback);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ public void onServiceFound(NsdServiceInfo service) {
preCommissionedVideoPlayers,
successCallback,
failureCallback,
nsdManagerResolverAvailState));
nsdManagerResolverAvailState,
1));
} else {
Log.d(TAG, "Ignoring discovered service: " + service.toString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,32 @@
import android.util.Log;
import chip.platform.NsdManagerServiceResolver;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class NsdResolveListener implements NsdManager.ResolveListener {

private static final String TAG = NsdResolveListener.class.getSimpleName();

private static final int MAX_RESOLUTION_ATTEMPTS = 5;
private static final int RESOLUTION_ATTEMPT_DELAY_SECS = 1;

private final NsdManager nsdManager;
private final List<Long> deviceTypeFilter;
private final List<VideoPlayer> preCommissionedVideoPlayers;
private final SuccessCallback<DiscoveredNodeData> successCallback;
private final FailureCallback failureCallback;
private final NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState;
private final int resolutionAttemptNumber;

public NsdResolveListener(
NsdManager nsdManager,
List<Long> deviceTypeFilter,
List<VideoPlayer> preCommissionedVideoPlayers,
SuccessCallback<DiscoveredNodeData> successCallback,
FailureCallback failureCallback,
NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState) {
NsdManagerServiceResolver.NsdManagerResolverAvailState nsdManagerResolverAvailState,
int resolutionAttemptNumber) {
this.nsdManager = nsdManager;
this.deviceTypeFilter = deviceTypeFilter;
this.preCommissionedVideoPlayers = preCommissionedVideoPlayers;
Expand All @@ -52,6 +59,7 @@ public NsdResolveListener(
this.successCallback = successCallback;
this.failureCallback = failureCallback;
this.nsdManagerResolverAvailState = nsdManagerResolverAvailState;
this.resolutionAttemptNumber = resolutionAttemptNumber;
}

@Override
Expand All @@ -77,15 +85,41 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
if (nsdManagerResolverAvailState != null) {
nsdManagerResolverAvailState.signalFree();
if (errorCode != NsdManager.FAILURE_ALREADY_ACTIVE
|| resolutionAttemptNumber >= MAX_RESOLUTION_ATTEMPTS) {
nsdManagerResolverAvailState.signalFree();
}
}

switch (errorCode) {
case NsdManager.FAILURE_ALREADY_ACTIVE:
Log.e(TAG, "NsdResolveListener FAILURE_ALREADY_ACTIVE - Service: " + serviceInfo);
failureCallback.handle(
new MatterError(
3, "NsdResolveListener FAILURE_ALREADY_ACTIVE - Service: " + serviceInfo));
if (resolutionAttemptNumber < MAX_RESOLUTION_ATTEMPTS) {
Log.d(TAG, "NsdResolveListener Scheduling a retry to resolve service " + serviceInfo);
Executors.newSingleThreadScheduledExecutor()
.schedule(
new Runnable() {
@Override
public void run() {
nsdManager.resolveService(
serviceInfo,
new NsdResolveListener(
nsdManager,
deviceTypeFilter,
preCommissionedVideoPlayers,
successCallback,
failureCallback,
nsdManagerResolverAvailState,
resolutionAttemptNumber + 1));
}
},
RESOLUTION_ATTEMPT_DELAY_SECS,
TimeUnit.SECONDS);
} else { // giving up
failureCallback.handle(
new MatterError(
3, "NsdResolveListener FAILURE_ALREADY_ACTIVE - Service: " + serviceInfo));
}
break;
case NsdManager.FAILURE_INTERNAL_ERROR:
Log.e(TAG, "NsdResolveListener FAILURE_INTERNAL_ERROR - Service: " + serviceInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
android:layout_height="wrap_content"
android:text="Skip to manual commissioning >>" />

<Button
android:id="@+id/discoverButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Discover>" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
objects = {

/* Begin PBXBuildFile section */
3C26AC8C2926FE0C00BA6881 /* DeviceAttestationCredentialsProviderImpl.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3C26AC8B2926FE0C00BA6881 /* DeviceAttestationCredentialsProviderImpl.hpp */; };
3C26AC902927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C26AC8F2927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm */; };
3C26AC9329282B8100BA6881 /* DeviceAttestationCredentialsHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C26AC9229282B8100BA6881 /* DeviceAttestationCredentialsHolder.m */; };
3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */; };
3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */; };
3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */; };
Expand All @@ -28,6 +31,10 @@

/* Begin PBXFileReference section */
3C0D9CDF2920A30C00D3332B /* CommissionableDataProviderImpl.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CommissionableDataProviderImpl.hpp; sourceTree = "<group>"; };
3C26AC8B2926FE0C00BA6881 /* DeviceAttestationCredentialsProviderImpl.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DeviceAttestationCredentialsProviderImpl.hpp; sourceTree = "<group>"; };
3C26AC8F2927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceAttestationCredentialsProviderImpl.mm; sourceTree = "<group>"; };
3C26AC91292700AD00BA6881 /* DeviceAttestationCredentialsHolder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceAttestationCredentialsHolder.h; sourceTree = "<group>"; };
3C26AC9229282B8100BA6881 /* DeviceAttestationCredentialsHolder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeviceAttestationCredentialsHolder.m; sourceTree = "<group>"; };
3C4AE64E286A7D40005B52A4 /* OnboardingPayload.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OnboardingPayload.h; sourceTree = "<group>"; };
3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnboardingPayload.m; sourceTree = "<group>"; };
3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaPlaybackTypes.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -113,6 +120,10 @@
3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */,
3C4E53B328E5185F00F293E8 /* TargetNavigatorTypes.h */,
3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */,
3C26AC91292700AD00BA6881 /* DeviceAttestationCredentialsHolder.h */,
3C26AC9229282B8100BA6881 /* DeviceAttestationCredentialsHolder.m */,
3C26AC8B2926FE0C00BA6881 /* DeviceAttestationCredentialsProviderImpl.hpp */,
3C26AC8F2927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm */,
3C0D9CDF2920A30C00D3332B /* CommissionableDataProviderImpl.hpp */,
);
path = MatterTvCastingBridge;
Expand All @@ -125,6 +136,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
3C26AC8C2926FE0C00BA6881 /* DeviceAttestationCredentialsProviderImpl.hpp in Headers */,
3CCB8740286A593700771BAD /* CastingServerBridge.h in Headers */,
3CCB8742286A593700771BAD /* ConversionUtils.hpp in Headers */,
3CCB8741286A593700771BAD /* DiscoveredNodeData.h in Headers */,
Expand Down Expand Up @@ -229,6 +241,8 @@
3CCB8744286A593700771BAD /* ConversionUtils.mm in Sources */,
3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */,
3C66FBFC290327BB00B63FE7 /* AppParameters.mm in Sources */,
3C26AC9329282B8100BA6881 /* DeviceAttestationCredentialsHolder.m in Sources */,
3C26AC902927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm in Sources */,
3CCB873F286A593700771BAD /* DiscoveredNodeData.mm in Sources */,
3C81C74C28F7A777001CB9D1 /* ContentApp.mm in Sources */,
3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#import <Foundation/Foundation.h>

#import "DeviceAttestationCredentialsHolder.h"
#import "OnboardingPayload.h"

#ifndef AppParameters_h
Expand All @@ -34,6 +35,8 @@

@property NSData * spake2pVerifier;

@property DeviceAttestationCredentialsHolder * deviceAttestationCredentials;

@end

#endif /* AppParameters_h */
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#import "CommissionableDataProviderImpl.hpp"
#import "ConversionUtils.hpp"
#import "DeviceAttestationCredentialsProviderImpl.hpp"
#import "MatterCallbacks.h"
#import "OnboardingPayload.h"

Expand All @@ -39,6 +40,8 @@ @interface CastingServerBridge ()

@property chip::DeviceLayer::CommissionableDataProviderImpl * commissionableDataProvider;

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

// queue used to serialize all work performed by the CastingServerBridge
@property (atomic) dispatch_queue_t chipWorkQueue;

Expand Down Expand Up @@ -109,6 +112,7 @@ - (void)initApp:(AppParameters * _Nullable)appParameters

CHIP_ERROR err = CHIP_NO_ERROR;
_commissionableDataProvider = new chip::DeviceLayer::CommissionableDataProviderImpl();
_deviceAttestationCredentialsProvider = chip::Credentials::Examples::GetExampleDACProvider();
_appParameters = appParameters;
AppParams cppAppParams;
if (_appParameters != nil) {
Expand Down Expand Up @@ -137,16 +141,55 @@ - (void)initApp:(AppParameters * _Nullable)appParameters
_commissionableDataProvider->SetSetupDiscriminator(_appParameters.onboardingPayload.setupDiscriminator);
}

uint32_t setupPasscode = 0;
uint16_t setupDiscriminator = 0;
_commissionableDataProvider->GetSetupPasscode(setupPasscode);
_commissionableDataProvider->GetSetupDiscriminator(setupDiscriminator);
_onboardingPayload = [[OnboardingPayload alloc] initWithSetupPasscode:setupPasscode setupDiscriminator:setupDiscriminator];
if (_appParameters.deviceAttestationCredentials != nil) {
NSData * certificationDeclarationNsData = _appParameters.deviceAttestationCredentials.getCertificationDeclaration;
chip::MutableByteSpan certificationDeclaration
= chip::MutableByteSpan(const_cast<uint8_t *>(static_cast<const uint8_t *>(certificationDeclarationNsData.bytes)),
certificationDeclarationNsData.length);

NSData * firmwareInformationNsData = _appParameters.deviceAttestationCredentials.getFirmwareInformation;
chip::MutableByteSpan firmwareInformation
= chip::MutableByteSpan(const_cast<uint8_t *>(static_cast<const uint8_t *>(firmwareInformationNsData.bytes)),
firmwareInformationNsData.length);

NSData * deviceAttestationCertNsData = _appParameters.deviceAttestationCredentials.getDeviceAttestationCert;
chip::MutableByteSpan deviceAttestationCert
= chip::MutableByteSpan(const_cast<uint8_t *>(static_cast<const uint8_t *>(deviceAttestationCertNsData.bytes)),
deviceAttestationCertNsData.length);

NSData * productAttestationIntermediateCertNsData
= _appParameters.deviceAttestationCredentials.getProductAttestationIntermediateCert;
chip::MutableByteSpan productAttestationIntermediateCert = chip::MutableByteSpan(
const_cast<uint8_t *>(static_cast<const uint8_t *>(productAttestationIntermediateCertNsData.bytes)),
productAttestationIntermediateCertNsData.length);

NSData * deviceAttestationCertPrivateKeyNsData
= _appParameters.deviceAttestationCredentials.getDeviceAttestationCertPrivateKey;
chip::MutableByteSpan deviceAttestationCertPrivateKey = chip::MutableByteSpan(
const_cast<uint8_t *>(static_cast<const uint8_t *>(deviceAttestationCertPrivateKeyNsData.bytes)),
deviceAttestationCertPrivateKeyNsData.length);

NSData * deviceAttestationCertPublicKeyKeyNsData
= _appParameters.deviceAttestationCredentials.getDeviceAttestationCertPublicKeyKey;
chip::MutableByteSpan deviceAttestationCertPublicKeyKey = chip::MutableByteSpan(
const_cast<uint8_t *>(static_cast<const uint8_t *>(deviceAttestationCertPublicKeyKeyNsData.bytes)),
deviceAttestationCertPublicKeyKeyNsData.length);

_deviceAttestationCredentialsProvider = new DeviceAttestationCredentialsProviderImpl(&certificationDeclaration,
&firmwareInformation, &deviceAttestationCert, &productAttestationIntermediateCert, &deviceAttestationCertPrivateKey,
&deviceAttestationCertPublicKeyKey);
}
}
chip::DeviceLayer::SetCommissionableDataProvider(_commissionableDataProvider);

uint32_t setupPasscode = 0;
uint16_t setupDiscriminator = 0;
_commissionableDataProvider->GetSetupPasscode(setupPasscode);
_commissionableDataProvider->GetSetupDiscriminator(setupDiscriminator);
_onboardingPayload = [[OnboardingPayload alloc] initWithSetupPasscode:setupPasscode setupDiscriminator:setupDiscriminator];

// Initialize device attestation config
SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());
SetDeviceAttestationCredentialsProvider(_deviceAttestationCredentialsProvider);

// Initialize device attestation verifier from a constant version
{
Expand Down Expand Up @@ -176,7 +219,7 @@ - (void)initApp:(AppParameters * _Nullable)appParameters
dispatch_async(_chipWorkQueue, ^{
CHIP_ERROR err = CHIP_NO_ERROR;
AppParams appParam;
if (appParameters != nil) {
if (appParameters == nil) {
err = CastingServer::GetInstance()->Init();
} else if ((err = [ConversionUtils convertToCppAppParamsInfoFrom:appParameters outAppParams:appParam]) == CHIP_NO_ERROR) {
err = CastingServer::GetInstance()->Init(&appParam);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
*
* Copyright (c) 2020-2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#import <Foundation/Foundation.h>

#ifndef DeviceAttestationCredentialsHolder_h
#define DeviceAttestationCredentialsHolder_h

@interface DeviceAttestationCredentialsHolder : NSObject

- (DeviceAttestationCredentialsHolder * _Nonnull)
initWithCertificationDeclaration:(NSData * _Nonnull)certificationDeclaration
firmwareInformation:(NSData * _Nonnull)firmwareInformation
deviceAttestationCert:(NSData * _Nonnull)deviceAttestationCert
productAttestationIntermediateCert:(NSData * _Nonnull)productAttestationIntermediateCert
deviceAttestationCertPrivateKey:(NSData * _Nonnull)deviceAttestationCertPrivateKey
deviceAttestationCertPublicKeyKey:(NSData * _Nonnull)deviceAttestationCertPublicKeyKey;

- (NSData * _Nonnull)getCertificationDeclaration;

- (NSData * _Nonnull)getFirmwareInformation;

- (NSData * _Nonnull)getDeviceAttestationCert;

- (NSData * _Nonnull)getProductAttestationIntermediateCert;

- (NSData * _Nonnull)getDeviceAttestationCertPrivateKey;

- (NSData * _Nonnull)getDeviceAttestationCertPublicKeyKey;

@end

#endif /* DeviceAttestationCredentialsHolder_h */
Loading

0 comments on commit 53a4db1

Please sign in to comment.