From cd41f0b89867f06d642c5621a7c37cb5235d854c Mon Sep 17 00:00:00 2001 From: Sharad Binjola <31142146+sharadb-amazon@users.noreply.github.com> Date: Wed, 6 Sep 2023 08:17:41 -0700 Subject: [PATCH] iOS tv-casting-app: refactored Initialization (#29002) --- .../project.pbxproj | 58 +++++ .../MatterTvCastingBridge/MTRCastingApp.h | 53 +++++ .../MatterTvCastingBridge/MTRCastingApp.mm | 115 +++++++++ .../MTRCommissionableData.h | 43 ++++ .../MTRCommissionableData.mm | 39 +++ .../MTRCommissionableDataProvider.h | 71 ++++++ .../MTRCommissionableDataProvider.mm | 225 ++++++++++++++++++ ...CommonCaseDeviceServerInitParamsProvider.h | 42 ++++ .../MatterTvCastingBridge/MTRDataSource.h | 36 +++ .../MTRDeviceAttestationCredentials.h | 42 ++++ .../MTRDeviceAttestationCredentials.mm | 37 +++ .../MTRDeviceAttestationCredentialsProvider.h | 55 +++++ ...MTRDeviceAttestationCredentialsProvider.mm | 132 ++++++++++ .../MTRRotatingDeviceIdUniqueIdProvider.h | 46 ++++ .../MTRRotatingDeviceIdUniqueIdProvider.mm | 54 +++++ .../MatterTvCastingBridge/MatterError.h | 4 + .../MatterTvCastingBridge/MatterError.mm | 43 ++++ .../MatterTvCastingBridge.h | 6 + .../TvCasting.xcodeproj/project.pbxproj | 6 +- .../xcschemes/TvCasting Release.xcscheme | 7 + .../xcshareddata/xcschemes/TvCasting.xcscheme | 7 + .../TvCasting/TvCasting/ContentView.swift | 5 +- .../TvCasting/MTRInitializationExample.swift | 92 +++++++ .../TvCasting/TvCasting/TvCastingApp.swift | 92 +++++-- examples/tv-casting-app/darwin/args.gni | 6 +- .../tv-casting-app/tv-casting-common/BUILD.gn | 6 +- .../tv-casting-common/core/CastingApp.cpp | 12 +- 27 files changed, 1300 insertions(+), 34 deletions(-) create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommonCaseDeviceServerInitParamsProvider.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDataSource.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.mm create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.h create mode 100644 examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.mm create mode 100644 examples/tv-casting-app/darwin/TvCasting/TvCasting/MTRInitializationExample.swift diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj index cbc52e427053d4..75b1e3a695f520 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj @@ -15,6 +15,9 @@ 3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */; }; 3C4E53B628E5595A00F293E8 /* ContentLauncherTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */; }; 3C66FBFC290327BB00B63FE7 /* AppParameters.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C66FBFB290327BB00B63FE7 /* AppParameters.mm */; }; + 3C6920462AA1093300D0F613 /* MTRDeviceAttestationCredentialsProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C6920452AA1093300D0F613 /* MTRDeviceAttestationCredentialsProvider.h */; }; + 3C6920482AA1094000D0F613 /* MTRDeviceAttestationCredentialsProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C6920472AA1094000D0F613 /* MTRDeviceAttestationCredentialsProvider.mm */; }; + 3C69204C2AA136BA00D0F613 /* MTRCommonCaseDeviceServerInitParamsProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C69204B2AA136BA00D0F613 /* MTRCommonCaseDeviceServerInitParamsProvider.h */; }; 3C81C74C28F7A777001CB9D1 /* ContentApp.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C74B28F7A777001CB9D1 /* ContentApp.mm */; }; 3C81C75028F7A7D3001CB9D1 /* VideoPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C74F28F7A7D3001CB9D1 /* VideoPlayer.m */; }; 3CCB87212869085400771BAD /* MatterTvCastingBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB87202869085400771BAD /* MatterTvCastingBridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -27,9 +30,20 @@ 3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873D286A593700771BAD /* CastingServerBridge.mm */; }; 3CCB8744286A593700771BAD /* ConversionUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873E286A593700771BAD /* ConversionUtils.mm */; }; 3CD6D01A298CDA2100D7569A /* CommissionerDiscoveryDelegateImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CD6D019298CDA2100D7569A /* CommissionerDiscoveryDelegateImpl.h */; }; + 3CD73F172A9E6884009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CD73F162A9E6884009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.h */; }; + 3CD73F192A9E68A7009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CD73F182A9E68A7009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.mm */; }; + 3CD73F1C2A9E8396009D82D1 /* MTRCommissionableDataProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CD73F1B2A9E8396009D82D1 /* MTRCommissionableDataProvider.h */; }; + 3CD73F1E2A9E83C1009D82D1 /* MTRCommissionableDataProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CD73F1D2A9E83C1009D82D1 /* MTRCommissionableDataProvider.mm */; }; + 3CD73F202A9EA060009D82D1 /* MTRDeviceAttestationCredentials.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CD73F1F2A9EA060009D82D1 /* MTRDeviceAttestationCredentials.h */; }; + 3CD73F222A9EA078009D82D1 /* MTRDeviceAttestationCredentials.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CD73F212A9EA077009D82D1 /* MTRDeviceAttestationCredentials.mm */; }; 3CE5ECCE2A673B30007CF331 /* CommissioningCallbackHandlers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CE5ECCD2A673B30007CF331 /* CommissioningCallbackHandlers.h */; }; 3CE5ECD02A673E2C007CF331 /* CommissioningCallbackHandlers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CE5ECCF2A673E2C007CF331 /* CommissioningCallbackHandlers.m */; }; 3CE868F42946D76200FCB92B /* CommissionableDataProviderImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CE868F32946D76200FCB92B /* CommissionableDataProviderImpl.mm */; }; + 3CF71C0A2A992D0D003A5CE5 /* MTRCastingApp.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CF71C092A992D0D003A5CE5 /* MTRCastingApp.h */; }; + 3CF71C0C2A992D25003A5CE5 /* MTRCastingApp.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF71C0B2A992D25003A5CE5 /* MTRCastingApp.mm */; }; + 3CF71C0E2A992DA2003A5CE5 /* MTRDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CF71C0D2A992DA2003A5CE5 /* MTRDataSource.h */; }; + 3CF71C102A99312D003A5CE5 /* MTRCommissionableData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CF71C0F2A99312D003A5CE5 /* MTRCommissionableData.h */; }; + 3CF71C122A993298003A5CE5 /* MTRCommissionableData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF71C112A993298003A5CE5 /* MTRCommissionableData.mm */; }; 3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF8532628E37F1000F07B9F /* MatterError.mm */; }; /* End PBXBuildFile section */ @@ -48,6 +62,9 @@ 3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentLauncherTypes.mm; sourceTree = ""; }; 3C66FBFA2903279A00B63FE7 /* AppParameters.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppParameters.h; sourceTree = ""; }; 3C66FBFB290327BB00B63FE7 /* AppParameters.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AppParameters.mm; sourceTree = ""; }; + 3C6920452AA1093300D0F613 /* MTRDeviceAttestationCredentialsProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceAttestationCredentialsProvider.h; sourceTree = ""; }; + 3C6920472AA1094000D0F613 /* MTRDeviceAttestationCredentialsProvider.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceAttestationCredentialsProvider.mm; sourceTree = ""; }; + 3C69204B2AA136BA00D0F613 /* MTRCommonCaseDeviceServerInitParamsProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCommonCaseDeviceServerInitParamsProvider.h; sourceTree = ""; }; 3C81C74B28F7A777001CB9D1 /* ContentApp.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentApp.mm; sourceTree = ""; }; 3C81C74E28F7A7AE001CB9D1 /* ContentApp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentApp.h; sourceTree = ""; }; 3C81C74F28F7A7D3001CB9D1 /* VideoPlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VideoPlayer.m; sourceTree = ""; }; @@ -64,9 +81,20 @@ 3CCB873D286A593700771BAD /* CastingServerBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CastingServerBridge.mm; sourceTree = ""; }; 3CCB873E286A593700771BAD /* ConversionUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConversionUtils.mm; sourceTree = ""; }; 3CD6D019298CDA2100D7569A /* CommissionerDiscoveryDelegateImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommissionerDiscoveryDelegateImpl.h; sourceTree = ""; }; + 3CD73F162A9E6884009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRRotatingDeviceIdUniqueIdProvider.h; sourceTree = ""; }; + 3CD73F182A9E68A7009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRRotatingDeviceIdUniqueIdProvider.mm; sourceTree = ""; }; + 3CD73F1B2A9E8396009D82D1 /* MTRCommissionableDataProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCommissionableDataProvider.h; sourceTree = ""; }; + 3CD73F1D2A9E83C1009D82D1 /* MTRCommissionableDataProvider.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCommissionableDataProvider.mm; sourceTree = ""; }; + 3CD73F1F2A9EA060009D82D1 /* MTRDeviceAttestationCredentials.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceAttestationCredentials.h; sourceTree = ""; }; + 3CD73F212A9EA077009D82D1 /* MTRDeviceAttestationCredentials.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceAttestationCredentials.mm; sourceTree = ""; }; 3CE5ECCD2A673B30007CF331 /* CommissioningCallbackHandlers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommissioningCallbackHandlers.h; sourceTree = ""; }; 3CE5ECCF2A673E2C007CF331 /* CommissioningCallbackHandlers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CommissioningCallbackHandlers.m; sourceTree = ""; }; 3CE868F32946D76200FCB92B /* CommissionableDataProviderImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CommissionableDataProviderImpl.mm; sourceTree = ""; }; + 3CF71C092A992D0D003A5CE5 /* MTRCastingApp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCastingApp.h; sourceTree = ""; }; + 3CF71C0B2A992D25003A5CE5 /* MTRCastingApp.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCastingApp.mm; sourceTree = ""; }; + 3CF71C0D2A992DA2003A5CE5 /* MTRDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDataSource.h; sourceTree = ""; }; + 3CF71C0F2A99312D003A5CE5 /* MTRCommissionableData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCommissionableData.h; sourceTree = ""; }; + 3CF71C112A993298003A5CE5 /* MTRCommissionableData.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCommissionableData.mm; sourceTree = ""; }; 3CF8532528E37ED800F07B9F /* MatterError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MatterError.h; sourceTree = ""; }; 3CF8532628E37F1000F07B9F /* MatterError.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MatterError.mm; sourceTree = ""; }; /* End PBXFileReference section */ @@ -106,6 +134,20 @@ isa = PBXGroup; children = ( 3CCB87202869085400771BAD /* MatterTvCastingBridge.h */, + 3CF71C092A992D0D003A5CE5 /* MTRCastingApp.h */, + 3CF71C0B2A992D25003A5CE5 /* MTRCastingApp.mm */, + 3CF71C0D2A992DA2003A5CE5 /* MTRDataSource.h */, + 3CF71C0F2A99312D003A5CE5 /* MTRCommissionableData.h */, + 3CF71C112A993298003A5CE5 /* MTRCommissionableData.mm */, + 3CD73F1B2A9E8396009D82D1 /* MTRCommissionableDataProvider.h */, + 3CD73F1D2A9E83C1009D82D1 /* MTRCommissionableDataProvider.mm */, + 3CD73F162A9E6884009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.h */, + 3CD73F182A9E68A7009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.mm */, + 3CD73F1F2A9EA060009D82D1 /* MTRDeviceAttestationCredentials.h */, + 3CD73F212A9EA077009D82D1 /* MTRDeviceAttestationCredentials.mm */, + 3C6920452AA1093300D0F613 /* MTRDeviceAttestationCredentialsProvider.h */, + 3C6920472AA1094000D0F613 /* MTRDeviceAttestationCredentialsProvider.mm */, + 3C69204B2AA136BA00D0F613 /* MTRCommonCaseDeviceServerInitParamsProvider.h */, 3CCB873A286A593700771BAD /* CastingServerBridge.h */, 3CCB873D286A593700771BAD /* CastingServerBridge.mm */, 3C66FBFA2903279A00B63FE7 /* AppParameters.h */, @@ -148,13 +190,21 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 3C69204C2AA136BA00D0F613 /* MTRCommonCaseDeviceServerInitParamsProvider.h in Headers */, 3CD6D01A298CDA2100D7569A /* CommissionerDiscoveryDelegateImpl.h in Headers */, + 3CF71C0E2A992DA2003A5CE5 /* MTRDataSource.h in Headers */, 3C26AC8C2926FE0C00BA6881 /* DeviceAttestationCredentialsProviderImpl.hpp in Headers */, + 3CD73F1C2A9E8396009D82D1 /* MTRCommissionableDataProvider.h in Headers */, + 3CF71C0A2A992D0D003A5CE5 /* MTRCastingApp.h in Headers */, + 3CD73F172A9E6884009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.h in Headers */, + 3CF71C102A99312D003A5CE5 /* MTRCommissionableData.h in Headers */, + 3CD73F202A9EA060009D82D1 /* MTRDeviceAttestationCredentials.h in Headers */, 3CCB8740286A593700771BAD /* CastingServerBridge.h in Headers */, 3CE5ECCE2A673B30007CF331 /* CommissioningCallbackHandlers.h in Headers */, 3CCB8742286A593700771BAD /* ConversionUtils.hpp in Headers */, 3CCB8741286A593700771BAD /* DiscoveredNodeData.h in Headers */, 3CCB87212869085400771BAD /* MatterTvCastingBridge.h in Headers */, + 3C6920462AA1093300D0F613 /* MTRDeviceAttestationCredentialsProvider.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -256,18 +306,24 @@ files = ( 3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */, 3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */, + 3C6920482AA1094000D0F613 /* MTRDeviceAttestationCredentialsProvider.mm in Sources */, 3CE5ECD02A673E2C007CF331 /* CommissioningCallbackHandlers.m in Sources */, + 3CD73F192A9E68A7009D82D1 /* MTRRotatingDeviceIdUniqueIdProvider.mm in Sources */, 3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */, 3C4E53B628E5595A00F293E8 /* ContentLauncherTypes.mm in Sources */, 3C81C75028F7A7D3001CB9D1 /* VideoPlayer.m in Sources */, 3CCB8744286A593700771BAD /* ConversionUtils.mm in Sources */, + 3CF71C0C2A992D25003A5CE5 /* MTRCastingApp.mm in Sources */, 3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */, + 3CD73F1E2A9E83C1009D82D1 /* MTRCommissionableDataProvider.mm in Sources */, + 3CD73F222A9EA078009D82D1 /* MTRDeviceAttestationCredentials.mm in Sources */, 3C66FBFC290327BB00B63FE7 /* AppParameters.mm in Sources */, 3CE868F42946D76200FCB92B /* CommissionableDataProviderImpl.mm in Sources */, 3C26AC9329282B8100BA6881 /* DeviceAttestationCredentialsHolder.m in Sources */, 3C26AC902927008900BA6881 /* DeviceAttestationCredentialsProviderImpl.mm in Sources */, 3CCB873F286A593700771BAD /* DiscoveredNodeData.mm in Sources */, 3C81C74C28F7A777001CB9D1 /* ContentApp.mm in Sources */, + 3CF71C122A993298003A5CE5 /* MTRCommissionableData.mm in Sources */, 3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -418,6 +474,7 @@ GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ( "${CHIP_ROOT}/examples/tv-casting-app/tv-casting-common/include", + "${CHIP_ROOT}/examples/tv-casting-app/tv-casting-common", "$(CHIP_ROOT)/src", "$(CHIP_ROOT)/src/include", "$(CHIP_ROOT)/src/lib", @@ -498,6 +555,7 @@ GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ( "${CHIP_ROOT}/examples/tv-casting-app/tv-casting-common/include", + "${CHIP_ROOT}/examples/tv-casting-app/tv-casting-common", "$(CHIP_ROOT)/src", "$(CHIP_ROOT)/src/include", "$(CHIP_ROOT)/src/lib", diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.h new file mode 100644 index 00000000000000..37a07e36452767 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.h @@ -0,0 +1,53 @@ +/** + * + * Copyright (c) 2023 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 "MTRDataSource.h" +#import "MatterError.h" + +#ifndef MTRCastingApp_h +#define MTRCastingApp_h + +/** + * @brief MTRCastingApp represents an app that can cast content to a Casting Player. + */ +@interface MTRCastingApp : NSObject + +/** + * Returns a shared instance of the MTRCastingApp + */ ++ (MTRCastingApp * _Nullable)getSharedInstance; + +/** + * @brief Initializes the MTRCastingApp with appParameters + * + * @param dataSource provides all the parameters required to initialize the MTRCastingApp + */ +- (MatterError * _Nonnull)initializeWithDataSource:(id _Nonnull)dataSource; + +/** + * @brief Starts the Matter server that the MTRCastingApp runs on and registers all the necessary delegates + */ +- (MatterError * _Nonnull)start; + +/** + * @brief Stops the Matter server that the MTRCastingApp runs on + */ +- (MatterError * _Nonnull)stop; + +@end + +#endif /* MTRCastingApp_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.mm new file mode 100644 index 00000000000000..1ee0bc98bb2805 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCastingApp.mm @@ -0,0 +1,115 @@ +/** + * + * Copyright (c) 2023 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 "MTRCastingApp.h" + +#import "MTRCommissionableDataProvider.h" +#import "MTRCommonCaseDeviceServerInitParamsProvider.h" +#import "MTRDeviceAttestationCredentialsProvider.h" +#import "MTRRotatingDeviceIdUniqueIdProvider.h" + +#import "core/Types.h" +#include +#include + +#import + +@interface MTRCastingApp () + +@property matter::casting::support::AppParameters appParameters; +@property matter::casting::support::MTRRotatingDeviceIdUniqueIdProvider uniqueIdProvider; +@property matter::casting::support::MTRCommissionableDataProvider * commissionableDataProvider; +@property matter::casting::support::MTRDeviceAttestationCredentialsProvider * dacProvider; +@property MTRCommonCaseDeviceServerInitParamsProvider * serverInitParamsProvider; + +// queue used to serialize all work performed by the CastingServerBridge +@property (atomic) dispatch_queue_t chipWorkQueue; + +@end + +@implementation MTRCastingApp + ++ (MTRCastingApp * _Nullable)getSharedInstance +{ + static MTRCastingApp * instance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] init]; + }); + return instance; +} + +- (MatterError * _Nonnull)initializeWithDataSource:(id _Nonnull)dataSource +{ + ChipLogProgress(AppServer, "MTRCastingApp.initializeWithDataSource called"); + + // Initialize cpp Providers + VerifyOrReturnValue(_uniqueIdProvider.Initialize(dataSource) == CHIP_NO_ERROR, MATTER_ERROR_INVALID_ARGUMENT); + + _commissionableDataProvider = new matter::casting::support::MTRCommissionableDataProvider(); + VerifyOrReturnValue(_commissionableDataProvider->Initialize(dataSource) == CHIP_NO_ERROR, MATTER_ERROR_INVALID_ARGUMENT); + + _dacProvider = new matter::casting::support::MTRDeviceAttestationCredentialsProvider(); + VerifyOrReturnValue(_dacProvider->Initialize(dataSource) == CHIP_NO_ERROR, MATTER_ERROR_INVALID_ARGUMENT); + + _serverInitParamsProvider = new MTRCommonCaseDeviceServerInitParamsProvider(); + + // Create cpp AppParameters + VerifyOrReturnValue(_appParameters.Create(&_uniqueIdProvider, _commissionableDataProvider, _dacProvider, + GetDefaultDACVerifier(chip::Credentials::GetTestAttestationTrustStore()), _serverInitParamsProvider) + == CHIP_NO_ERROR, + MATTER_ERROR_INVALID_ARGUMENT); + + // Initialize cpp CastingApp + VerifyOrReturnValue(matter::casting::core::CastingApp::GetInstance()->Initialize(_appParameters) == CHIP_NO_ERROR, + MATTER_ERROR_INCORRECT_STATE); + + // Get and store the CHIP Work queue + _chipWorkQueue = chip::DeviceLayer::PlatformMgrImpl().GetWorkQueue(); + + return MATTER_NO_ERROR; +} + +- (MatterError * _Nonnull)start +{ + ChipLogProgress(AppServer, "MTRCastingApp.start called"); + VerifyOrReturnValue(_chipWorkQueue != nil, MATTER_ERROR_INCORRECT_STATE); + + __block CHIP_ERROR err = CHIP_NO_ERROR; + + dispatch_sync(_chipWorkQueue, ^{ + err = matter::casting::core::CastingApp::GetInstance()->Start(); + }); + + return err == CHIP_NO_ERROR ? MATTER_NO_ERROR : MATTER_ERROR_INCORRECT_STATE; +} + +- (MatterError * _Nonnull)stop +{ + ChipLogProgress(AppServer, "MTRCastingApp.stop called"); + VerifyOrReturnValue(_chipWorkQueue != nil, MATTER_ERROR_INCORRECT_STATE); + + __block CHIP_ERROR err = CHIP_NO_ERROR; + + dispatch_sync(_chipWorkQueue, ^{ + err = matter::casting::core::CastingApp::GetInstance()->Stop(); + }); + + return err == CHIP_NO_ERROR ? MATTER_NO_ERROR : MATTER_ERROR_INCORRECT_STATE; +} + +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.h new file mode 100644 index 00000000000000..59eb8acdb9eb53 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.h @@ -0,0 +1,43 @@ +/** + * + * Copyright (c) 2023 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 + +#ifndef MTRCommissionableData_h +#define MTRCommissionableData_h + +@interface MTRCommissionableData : NSObject + +@property (nonatomic, readonly) uint32_t passcode; + +@property (nonatomic, readonly) uint16_t discriminator; + +@property (nonatomic, readonly) uint32_t spake2pIterationCount; + +@property (nonatomic, strong, readonly) NSData * _Nullable spake2pVerifier; + +@property (nonatomic, strong, readonly) NSData * _Nullable spake2pSalt; + +- (instancetype _Nonnull)initWithPasscode:(uint32_t)passcode + discriminator:(uint16_t)discriminator + spake2pIterationCount:(uint32_t)spake2pIterationCount + spake2pVerifier:(NSData * _Nullable)spake2pVerifier + spake2pSalt:(NSData * _Nullable)spake2pSalt; + +@end + +#endif /* MTRCommissionableData_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.mm new file mode 100644 index 00000000000000..85858b36dffbd1 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableData.mm @@ -0,0 +1,39 @@ +/** + * + * Copyright (c) 2023 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 "MTRCommissionableData.h" +#import + +@implementation MTRCommissionableData + +- (instancetype)initWithPasscode:(uint32_t)passcode + discriminator:(uint16_t)discriminator + spake2pIterationCount:(uint32_t)spake2pIterationCount + spake2pVerifier:(NSData * _Nullable)spake2pVerifier + spake2pSalt:(NSData * _Nullable)spake2pSalt +{ + if (self = [super init]) { + _passcode = passcode; + _discriminator = discriminator; + _spake2pIterationCount = spake2pIterationCount; + _spake2pVerifier = spake2pVerifier; + _spake2pVerifier = spake2pVerifier; + } + return self; +} + +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.h new file mode 100644 index 00000000000000..8112207a003028 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.h @@ -0,0 +1,71 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#import "MTRDataSource.h" + +#include +#include +#include +#include +#include + +#ifndef MTRCommissionableDataProvider_h +#define MTRCommissionableDataProvider_h + +namespace matter { +namespace casting { +namespace support { + +class MTRCommissionableDataProvider : public chip::DeviceLayer::CommissionableDataProvider +{ +public: + CHIP_ERROR Initialize(id dataSource); + CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; + CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override + { + // We don't support overriding the discriminator post-init (it is deprecated!) + return CHIP_ERROR_NOT_IMPLEMENTED; + } + CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; + CHIP_ERROR GetSpake2pSalt(chip::MutableByteSpan & saltBuf) override; + CHIP_ERROR GetSpake2pVerifier(chip::MutableByteSpan & verifierBuf, size_t & outVerifierLen) override; + CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override; + CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override + { + // We don't support overriding the passcode post-init (it is deprecated!) + return CHIP_ERROR_NOT_IMPLEMENTED; + } + +private: + id mDataSource = nullptr; + + bool mFirstUpdated = false; + std::vector mSerializedPaseVerifier; + std::vector mPaseSalt; + uint32_t mPaseIterationCount = 0; + chip::Optional mSetupPasscode; + uint16_t mDiscriminator = 0; +}; + +}; // namespace support +}; // namespace casting +}; // namespace matter + +#endif /* MTRCommissionableDataProvider_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.mm new file mode 100644 index 00000000000000..6a6047984c1a8a --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommissionableDataProvider.mm @@ -0,0 +1,225 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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 "MTRCommissionableDataProvider.h" + +#import "MTRCommissionableData.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::Crypto; + +namespace matter { +namespace casting { + namespace support { + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT +#define CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT 1000 +#endif + + CHIP_ERROR GeneratePaseSalt(std::vector & spake2pSaltVector) + { + constexpr size_t kSaltLen = kSpake2p_Max_PBKDF_Salt_Length; + spake2pSaltVector.resize(kSaltLen); + return DRBG_get_bytes(spake2pSaltVector.data(), spake2pSaltVector.size()); + } + + CHIP_ERROR MTRCommissionableDataProvider::Initialize(id dataSource) + { + VerifyOrReturnLogError(dataSource != nil, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnLogError(mDataSource == nullptr, CHIP_ERROR_INCORRECT_STATE); + + mDataSource = dataSource; + MTRCommissionableData * commissionableData = + [mDataSource castingAppDidReceiveRequestForCommissionableData:@"MTRCommissionableDataProvider.Initialize()"]; + + VerifyOrReturnLogError(commissionableData.discriminator <= chip::kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT); + + uint32_t spake2pIterationCount = commissionableData.spake2pIterationCount; + if (spake2pIterationCount == 0) { + spake2pIterationCount = CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT; + } + VerifyOrReturnLogError( + static_cast(spake2pIterationCount) >= kSpake2p_Min_PBKDF_Iterations, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnLogError( + static_cast(spake2pIterationCount) <= kSpake2p_Max_PBKDF_Iterations, CHIP_ERROR_INVALID_ARGUMENT); + + const bool havePaseVerifier = (commissionableData.spake2pVerifier != nullptr); + const bool havePaseSalt = (commissionableData.spake2pSalt != nullptr); + VerifyOrReturnLogError(!havePaseVerifier || (havePaseVerifier && havePaseSalt), CHIP_ERROR_INVALID_ARGUMENT); + + CHIP_ERROR err; + // read verifier from paramter if provided + Spake2pVerifier providedVerifier; + std::vector serializedSpake2pVerifier(kSpake2p_VerifierSerialized_Length); + if (havePaseVerifier) { + size_t maxBase64Size = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length); + VerifyOrReturnLogError( + static_cast(commissionableData.spake2pVerifier.length) <= maxBase64Size, CHIP_ERROR_INVALID_ARGUMENT); + + size_t decodedLen = chip::Base64Decode32(reinterpret_cast(commissionableData.spake2pVerifier.bytes), + static_cast(commissionableData.spake2pVerifier.length), + reinterpret_cast(serializedSpake2pVerifier.data())); + VerifyOrReturnLogError(decodedLen == chip::Crypto::kSpake2p_VerifierSerialized_Length, CHIP_ERROR_INVALID_ARGUMENT); + + chip::MutableByteSpan verifierSpan { serializedSpake2pVerifier.data(), decodedLen }; + err = providedVerifier.Deserialize(verifierSpan); + VerifyOrReturnLogError(err == CHIP_NO_ERROR, err); + + ChipLogProgress(Support, "Got externally provided verifier, using it."); + } + + // read salt from paramter if provided or generate one + std::vector spake2pSalt(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length); + if (!havePaseSalt) { + ChipLogProgress(Support, "MTRCommissionableDataProvider didn't get a PASE salt, generating one."); + err = GeneratePaseSalt(spake2pSalt); + VerifyOrReturnLogError(err == CHIP_NO_ERROR, err); + } else { + size_t maxBase64Size = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length); + VerifyOrReturnLogError( + static_cast(commissionableData.spake2pSalt.length) <= maxBase64Size, CHIP_ERROR_INVALID_ARGUMENT); + + size_t decodedLen = chip::Base64Decode32(reinterpret_cast(commissionableData.spake2pSalt.bytes), + static_cast(commissionableData.spake2pSalt.length), reinterpret_cast(spake2pSalt.data())); + VerifyOrReturnLogError(decodedLen >= chip::Crypto::kSpake2p_Min_PBKDF_Salt_Length + && decodedLen <= chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length, + CHIP_ERROR_INVALID_ARGUMENT); + spake2pSalt.resize(decodedLen); + } + + // generate verifier from passcode if provided + const bool havePasscode + = (commissionableData.passcode > kMinSetupPasscode && commissionableData.passcode < kMaxSetupPasscode); + Spake2pVerifier passcodeVerifier; + std::vector serializedPasscodeVerifier(kSpake2p_VerifierSerialized_Length); + chip::MutableByteSpan saltSpan { spake2pSalt.data(), spake2pSalt.size() }; + if (havePasscode) { + uint32_t u32SetupPasscode = static_cast(commissionableData.passcode); + err = passcodeVerifier.Generate(spake2pIterationCount, saltSpan, u32SetupPasscode); + VerifyOrReturnLogError(err == CHIP_NO_ERROR, err); + + chip::MutableByteSpan verifierSpan { serializedPasscodeVerifier.data(), serializedPasscodeVerifier.size() }; + err = passcodeVerifier.Serialize(verifierSpan); + VerifyOrReturnLogError(err == CHIP_NO_ERROR, err); + } + + // Make sure we actually have a verifier + VerifyOrReturnLogError(havePasscode || havePaseVerifier, CHIP_ERROR_INVALID_ARGUMENT); + + // If both passcode and external verifier were provided, validate they match, otherwise + // it's ambiguous. + if (havePasscode && havePaseVerifier) { + VerifyOrReturnLogError(serializedPasscodeVerifier == serializedSpake2pVerifier, CHIP_ERROR_INVALID_ARGUMENT); + ChipLogProgress( + Support, "Validated externally provided passcode matches the one generated from provided passcode."); + } + + // External PASE verifier takes precedence when present (even though it is identical to passcode-based + // one when the latter is present). + if (havePaseVerifier) { + mSerializedPaseVerifier = std::move(serializedSpake2pVerifier); + } else { + mSerializedPaseVerifier = std::move(serializedPasscodeVerifier); + } + mDiscriminator = commissionableData.discriminator; + mPaseSalt = std::move(spake2pSalt); + mPaseIterationCount = spake2pIterationCount; + if (havePasscode) { + mSetupPasscode.SetValue(commissionableData.passcode); + } + + // Set to global CommissionableDataProvider once success first time + if (!mFirstUpdated) { + DeviceLayer::SetCommissionableDataProvider(this); + } + mFirstUpdated = true; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRCommissionableDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) + { + VerifyOrReturnError(mFirstUpdated, CHIP_ERROR_INCORRECT_STATE); + setupDiscriminator = mDiscriminator; + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRCommissionableDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) + { + ChipLogProgress(AppServer, "MTRCommissionableDataProvider::GetSpake2pIterationCount called"); + VerifyOrReturnLogError(mFirstUpdated, CHIP_ERROR_INCORRECT_STATE); + iterationCount = mPaseIterationCount; + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRCommissionableDataProvider::GetSpake2pSalt(chip::MutableByteSpan & saltBuf) + { + ChipLogProgress(AppServer, "MTRCommissionableDataProvider::GetSpake2pSalt called"); + VerifyOrReturnError(mFirstUpdated, CHIP_ERROR_INCORRECT_STATE); + + VerifyOrReturnError(saltBuf.size() >= kSpake2p_Max_PBKDF_Salt_Length, CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(saltBuf.data(), mPaseSalt.data(), mPaseSalt.size()); + saltBuf.reduce_size(mPaseSalt.size()); + + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRCommissionableDataProvider::GetSpake2pVerifier(chip::MutableByteSpan & verifierBuf, size_t & outVerifierLen) + { + ChipLogProgress(AppServer, "MTRCommissionableDataProvider::GetSpake2pVerifier called"); + VerifyOrReturnError(mFirstUpdated, CHIP_ERROR_INCORRECT_STATE); + + // By now, serialized verifier from Init should be correct size + VerifyOrReturnError(mSerializedPaseVerifier.size() == kSpake2p_VerifierSerialized_Length, CHIP_ERROR_INTERNAL); + + outVerifierLen = mSerializedPaseVerifier.size(); + VerifyOrReturnError(verifierBuf.size() >= outVerifierLen, CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(verifierBuf.data(), mSerializedPaseVerifier.data(), mSerializedPaseVerifier.size()); + verifierBuf.reduce_size(mSerializedPaseVerifier.size()); + + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRCommissionableDataProvider::GetSetupPasscode(uint32_t & setupPasscode) + { + ChipLogProgress(AppServer, "MTRCommissionableDataProvider::GetSetupPasscode called"); + VerifyOrReturnError(mFirstUpdated, CHIP_ERROR_INCORRECT_STATE); + + // Pretend not implemented if we don't have a passcode value externally set + if (!mSetupPasscode.HasValue()) { + return CHIP_ERROR_NOT_IMPLEMENTED; + } + + setupPasscode = mSetupPasscode.Value(); + ChipLogProgress(AppServer, "MTRCommissionableDataProvider::GetSetupPasscode returning value %d", setupPasscode); + return CHIP_NO_ERROR; + } + + }; // namespace support +}; // namespace casting +}; // namespace matter diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommonCaseDeviceServerInitParamsProvider.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommonCaseDeviceServerInitParamsProvider.h new file mode 100644 index 00000000000000..a22113074e31f1 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRCommonCaseDeviceServerInitParamsProvider.h @@ -0,0 +1,42 @@ +/** + * + * Copyright (c) 2023 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. + */ + +#include "core/Types.h" + +#ifndef MTRCommonCaseDeviceServerInitParamsProvider_h +#define MTRCommonCaseDeviceServerInitParamsProvider_h + +/** + * @brief Provides the ServerInitParams required to start the CastingApp, which in turn starts the Matter server + */ +class MTRCommonCaseDeviceServerInitParamsProvider : public matter::casting::support::ServerInitParamsProvider +{ +private: + // For this example, we'll use CommonCaseDeviceServerInitParams + chip::CommonCaseDeviceServerInitParams serverInitParams; + +public: + chip::ServerInitParams * Get() + { + CHIP_ERROR err = serverInitParams.InitializeStaticResourcesBeforeServerInit(); + VerifyOrReturnValue(err == CHIP_NO_ERROR, nullptr, + ChipLogError(AppServer, "Initialization of ServerInitParams failed %" CHIP_ERROR_FORMAT, err.Format())); + return &serverInitParams; + } +}; + +#endif /* MTRCommonCaseDeviceServerInitParamsProvider_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDataSource.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDataSource.h new file mode 100644 index 00000000000000..a350673b70f6c4 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDataSource.h @@ -0,0 +1,36 @@ +/** + * + * Copyright (c) 2023 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 "MTRCommissionableData.h" +#import "MTRDeviceAttestationCredentials.h" + +#ifndef MTRDataSource_h +#define MTRDataSource_h + +@protocol MTRDataSource + +- (dispatch_queue_t _Nonnull)clientQueue; + +- (NSData * _Nonnull)castingAppDidReceiveRequestForRotatingDeviceIdUniqueId:(id _Nonnull)sender; +- (MTRCommissionableData * _Nonnull)castingAppDidReceiveRequestForCommissionableData:(id _Nonnull)sender; +- (MTRDeviceAttestationCredentials * _Nonnull)castingAppDidReceiveRequestForDeviceAttestationCredentials:(id _Nonnull)sender; + +- (NSData * _Nonnull)castingApp:(id _Nonnull)sender didReceiveRequestToSignCertificateRequest:(NSData * _Nonnull)csrData; + +@end + +#endif /* MTRDataSource_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.h new file mode 100644 index 00000000000000..aed7eceedbacdd --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.h @@ -0,0 +1,42 @@ +/** + * + * Copyright (c) 2023 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 +#import + +#ifndef MTRDeviceAttestationCredentials_h +#define MTRDeviceAttestationCredentials_h + +@interface MTRDeviceAttestationCredentials : NSObject + +@property (nonatomic, strong, readonly) NSData * _Nonnull certificationDeclaration; + +@property (nonatomic, strong, readonly) NSData * _Nonnull firmwareInformation; + +@property (nonatomic, strong, readonly) NSData * _Nonnull deviceAttestationCert; + +@property (nonatomic, strong, readonly) NSData * _Nonnull productAttestationIntermediateCert; + +- (MTRDeviceAttestationCredentials * _Nonnull)initWithCertificationDeclaration:(NSData * _Nonnull)certificationDeclaration + firmwareInformation:(NSData * _Nonnull)firmwareInformation + deviceAttestationCert:(NSData * _Nonnull)deviceAttestationCert + productAttestationIntermediateCert: + (NSData * _Nonnull)productAttestationIntermediateCert; + +@end + +#endif /* MTRDeviceAttestationCredentials_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.mm new file mode 100644 index 00000000000000..1daa18a681c93c --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentials.mm @@ -0,0 +1,37 @@ +/** + * + * Copyright (c) 2023 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 "MTRDeviceAttestationCredentials.h" +#import + +@implementation MTRDeviceAttestationCredentials + +- (instancetype)initWithCertificationDeclaration:(NSData * _Nonnull)certificationDeclaration + firmwareInformation:(NSData * _Nonnull)firmwareInformation + deviceAttestationCert:(NSData * _Nonnull)deviceAttestationCert + productAttestationIntermediateCert:(NSData * _Nonnull)productAttestationIntermediateCert; +{ + if (self = [super init]) { + _certificationDeclaration = certificationDeclaration; + _firmwareInformation = firmwareInformation; + _deviceAttestationCert = deviceAttestationCert; + _productAttestationIntermediateCert = productAttestationIntermediateCert; + } + return self; +} + +@end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.h new file mode 100644 index 00000000000000..e955ac9ee7eb33 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.h @@ -0,0 +1,55 @@ +/** + * + * Copyright (c) 2023 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 "MTRDataSource.h" + +#include +#include +#include + +#import +#include + +#ifndef MTRDeviceAttestationCredentialsProvider_h +#define MTRDeviceAttestationCredentialsProvider_h + +namespace matter { +namespace casting { +namespace support { + +class MTRDeviceAttestationCredentialsProvider : public chip::Credentials::DeviceAttestationCredentialsProvider +{ +public: + CHIP_ERROR Initialize(id dataSource); + + CHIP_ERROR GetCertificationDeclaration(chip::MutableByteSpan & outCertificationDeclaration) override; + CHIP_ERROR GetFirmwareInformation(chip::MutableByteSpan & outFirmwareInformation) override; + CHIP_ERROR GetDeviceAttestationCert(chip::MutableByteSpan & outDeviceAttestationCert) override; + CHIP_ERROR GetProductAttestationIntermediateCert(chip::MutableByteSpan & outProductAttestationIntermediateCert) override; + CHIP_ERROR SignWithDeviceAttestationKey(const chip::ByteSpan & messageToSign, + chip::MutableByteSpan & outSignatureBuffer) override; + +private: + id mDataSource = nullptr; + MTRDeviceAttestationCredentials * mDac = nullptr; +}; + +}; // namespace support +}; // namespace casting +}; // namespace matter + +#endif /* MTRDeviceAttestationCredentialsProvider_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.mm new file mode 100644 index 00000000000000..8a2bcb0439c217 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRDeviceAttestationCredentialsProvider.mm @@ -0,0 +1,132 @@ +/* + * + * Copyright (c) 2023 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 "MTRDeviceAttestationCredentialsProvider.h" + +#import "MTRDeviceAttestationCredentials.h" + +#include "lib/support/logging/CHIPLogging.h" +#include +#include + +#import + +namespace matter { +namespace casting { + namespace support { + + CHIP_ERROR MTRDeviceAttestationCredentialsProvider::Initialize(id dataSource) + { + VerifyOrReturnError(dataSource != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mDataSource == nullptr, CHIP_ERROR_INCORRECT_STATE); + + mDac = [mDataSource + castingAppDidReceiveRequestForDeviceAttestationCredentials:@"MTRDeviceAttestationCredentialsProvider.Initialize()"]; + + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRDeviceAttestationCredentialsProvider::GetCertificationDeclaration( + chip::MutableByteSpan & outCertificationDeclaration) + { + VerifyOrReturnError(mDac != nullptr, CHIP_ERROR_INCORRECT_STATE); + + if (mDac.certificationDeclaration != nullptr && mDac.certificationDeclaration.length > 0) { + if (outCertificationDeclaration.size() >= mDac.certificationDeclaration.length) { + memcpy(outCertificationDeclaration.data(), mDac.certificationDeclaration.bytes, + mDac.certificationDeclaration.length); + outCertificationDeclaration.reduce_size(mDac.certificationDeclaration.length); + } else { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + } + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRDeviceAttestationCredentialsProvider::GetFirmwareInformation(chip::MutableByteSpan & outFirmwareInformation) + { + VerifyOrReturnError(mDac != nullptr, CHIP_ERROR_INCORRECT_STATE); + + if (mDac.firmwareInformation != nullptr && mDac.firmwareInformation.length > 0) { + if (outFirmwareInformation.size() >= mDac.firmwareInformation.length) { + memcpy(outFirmwareInformation.data(), mDac.firmwareInformation.bytes, mDac.firmwareInformation.length); + outFirmwareInformation.reduce_size(mDac.firmwareInformation.length); + } else { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + } + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRDeviceAttestationCredentialsProvider::GetDeviceAttestationCert( + chip::MutableByteSpan & outDeviceAttestationCert) + { + VerifyOrReturnError(mDac != nullptr, CHIP_ERROR_INCORRECT_STATE); + + if (mDac.deviceAttestationCert != nullptr && mDac.deviceAttestationCert.length > 0) { + if (outDeviceAttestationCert.size() >= mDac.deviceAttestationCert.length) { + memcpy(outDeviceAttestationCert.data(), mDac.deviceAttestationCert.bytes, mDac.deviceAttestationCert.length); + outDeviceAttestationCert.reduce_size(mDac.deviceAttestationCert.length); + } else { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + } + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRDeviceAttestationCredentialsProvider::GetProductAttestationIntermediateCert( + chip::MutableByteSpan & outProductAttestationIntermediateCert) + { + VerifyOrReturnError(mDac != nullptr, CHIP_ERROR_INCORRECT_STATE); + + if (mDac.productAttestationIntermediateCert != nullptr && mDac.productAttestationIntermediateCert.length > 0) { + if (outProductAttestationIntermediateCert.size() >= mDac.productAttestationIntermediateCert.length) { + memcpy(outProductAttestationIntermediateCert.data(), mDac.productAttestationIntermediateCert.bytes, + mDac.productAttestationIntermediateCert.length); + outProductAttestationIntermediateCert.reduce_size(mDac.productAttestationIntermediateCert.length); + } else { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + } + return CHIP_NO_ERROR; + } + + CHIP_ERROR MTRDeviceAttestationCredentialsProvider::SignWithDeviceAttestationKey( + const chip::ByteSpan & messageToSign, chip::MutableByteSpan & outSignatureBuffer) + { + VerifyOrReturnError(mDataSource != nullptr, CHIP_ERROR_INCORRECT_STATE); + + __block NSData * signedData = nil; + NSData * csrData = [NSData dataWithBytes:messageToSign.data() length:messageToSign.size()]; + dispatch_sync(mDataSource.clientQueue, ^{ + signedData = [mDataSource castingApp:@"MTRDeviceAttestationCredentialsProvider.SignWithDeviceAttestationKey()" + didReceiveRequestToSignCertificateRequest:csrData]; + }); + + if (signedData != nil && outSignatureBuffer.size() >= signedData.length) { + memcpy(outSignatureBuffer.data(), signedData.bytes, signedData.length); + outSignatureBuffer.reduce_size(signedData.length); + } else { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + return CHIP_NO_ERROR; + } + + }; // namespace support +}; // namespace casting +}; // namespace matter diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.h new file mode 100644 index 00000000000000..5f0b32a21b58e2 --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.h @@ -0,0 +1,46 @@ +/** + * + * Copyright (c) 2023 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 "MTRDataSource.h" + +#include "core/Types.h" + +#ifndef MTRRotatingDeviceIdUniqueIdProvider_h +#define MTRRotatingDeviceIdUniqueIdProvider_h + +namespace matter { +namespace casting { +namespace support { + +class MTRRotatingDeviceIdUniqueIdProvider : public matter::casting::support::MutableByteSpanDataProvider +{ +public: + CHIP_ERROR Initialize(id dataSource); + chip::MutableByteSpan * Get(); + +private: + id mDataSource = nullptr; + + chip::MutableByteSpan mRotatingDeviceIdUniqueIdSpan; + uint8_t mRotatingDeviceIdUniqueId[chip::DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength]; +}; + +}; // namespace support +}; // namespace casting +}; // namespace matter + +#endif /* MTRRotatingDeviceIdUniqueIdProvider_h */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.mm new file mode 100644 index 00000000000000..7db4ce55c91e7b --- /dev/null +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MTRRotatingDeviceIdUniqueIdProvider.mm @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2023 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. + */ + +#include "MTRRotatingDeviceIdUniqueIdProvider.h" + +#include "lib/support/logging/CHIPLogging.h" +#include +#include + +#import + +namespace matter { +namespace casting { + namespace support { + + CHIP_ERROR MTRRotatingDeviceIdUniqueIdProvider::Initialize(id dataSource) + { + VerifyOrReturnError(dataSource != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mDataSource == nullptr, CHIP_ERROR_INCORRECT_STATE); + mDataSource = dataSource; + return CHIP_NO_ERROR; + } + + chip::MutableByteSpan * MTRRotatingDeviceIdUniqueIdProvider::Get() + { + ChipLogProgress(AppServer, "MTRRotatingDeviceIdUniqueIdProvider.Get() called"); + VerifyOrReturnValue(mDataSource != nil, nullptr, ChipLogError(AppServer, "mDataSource found nil!")); + + NSData * uniqueIdData = + [mDataSource castingAppDidReceiveRequestForRotatingDeviceIdUniqueId:@"MTRRotatingDeviceIdUniqueIdProvider.Get()"]; + if (uniqueIdData != nil) { + mRotatingDeviceIdUniqueIdSpan = chip::MutableByteSpan( + const_cast(reinterpret_cast(uniqueIdData.bytes)), uniqueIdData.length); + } + return &mRotatingDeviceIdUniqueIdSpan; + } + + }; // namespace support +}; // namespace casting +}; // namespace matter diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h index ec018725294162..95aa22ebdd3577 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h @@ -26,6 +26,10 @@ @property NSString * _Nullable message; +extern MatterError * _Nonnull MATTER_NO_ERROR; +extern MatterError * _Nonnull MATTER_ERROR_INCORRECT_STATE; +extern MatterError * _Nonnull MATTER_ERROR_INVALID_ARGUMENT; + - (MatterError * _Nonnull)initWithCode:(uint32_t)code message:(NSString * _Nullable)message; @end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm index ce700e5a80338a..cbee1a455a51ca 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm @@ -19,8 +19,19 @@ #import "MatterError.h" +#include + @implementation MatterError +MatterError * MATTER_NO_ERROR = [[MatterError alloc] initWithCode:0 message:nil]; + +MatterError * MATTER_ERROR_INCORRECT_STATE = + [[MatterError alloc] initWithCode:CHIP_ERROR_INCORRECT_STATE.AsInteger() + message:[NSString stringWithUTF8String:CHIP_ERROR_INCORRECT_STATE.AsString()]]; +MatterError * MATTER_ERROR_INVALID_ARGUMENT = + [[MatterError alloc] initWithCode:CHIP_ERROR_INVALID_ARGUMENT.AsInteger() + message:[NSString stringWithUTF8String:CHIP_ERROR_INVALID_ARGUMENT.AsString()]]; + - (MatterError *)initWithCode:(uint32_t)code message:(NSString * _Nullable)message { self = [super init]; @@ -36,4 +47,36 @@ - (NSString *)description return [NSString stringWithFormat:@"MatterError: code=%d message=%@", _code, _message]; } +- (BOOL)isEqualToMatterError:(MatterError *)other +{ + return self.code == other.code; +} + +- (BOOL)isEqual:(id)other +{ + if (other == nil) { + return NO; + } + + if (self == other) { + return YES; + } + + if (![other isKindOfClass:[MatterError class]]) { + return NO; + } + + return [self isEqualToMatterError:(MatterError *) other]; +} + +- (NSUInteger)hash +{ + const NSUInteger prime = 31; + NSUInteger result = 1; + + result = prime * result + self.code; + + return result; +} + @end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterTvCastingBridge.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterTvCastingBridge.h index 709740914e9ca8..9d12b964ce1c97 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterTvCastingBridge.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterTvCastingBridge.h @@ -24,3 +24,9 @@ FOUNDATION_EXPORT double MatterTvCastingBridgeVersionNumber; FOUNDATION_EXPORT const unsigned char MatterTvCastingBridgeVersionString[]; #import "CastingServerBridge.h" + +// Add simplified casting API headers here +#import "MTRCastingApp.h" +#import "MTRCommissionableData.h" +#import "MTRDataSource.h" +#import "MTRDeviceAttestationCredentials.h" diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj index 68c5808353ab5a..567a0e205d1fc6 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 3C69204A2AA1368F00D0F613 /* MTRInitializationExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C6920492AA1368F00D0F613 /* MTRInitializationExample.swift */; }; 3C81C75328F8C79E001CB9D1 /* StartFromCacheView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C75228F8C79E001CB9D1 /* StartFromCacheView.swift */; }; 3C81C75528F8C7B6001CB9D1 /* StartFromCacheViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C75428F8C7B6001CB9D1 /* StartFromCacheViewModel.swift */; }; 3C81C75728F8E418001CB9D1 /* ConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C81C75628F8E418001CB9D1 /* ConnectionView.swift */; }; @@ -46,6 +47,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 3C6920492AA1368F00D0F613 /* MTRInitializationExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MTRInitializationExample.swift; sourceTree = ""; }; 3C75075E284C1DF800D7DB3A /* TvCasting.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TvCasting.entitlements; sourceTree = ""; }; 3C7507AC285299DF00D7DB3A /* CommissionerDiscoveryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommissionerDiscoveryView.swift; sourceTree = ""; }; 3C7507AE28529A5F00D7DB3A /* CommissioningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommissioningView.swift; sourceTree = ""; }; @@ -115,9 +117,10 @@ children = ( 3CC0E8FD2841DD3500EC6A18 /* Assets.xcassets */, 3C75075E284C1DF800D7DB3A /* TvCasting.entitlements */, + 3CC0E8F92841DD3400EC6A18 /* TvCastingApp.swift */, + 3C6920492AA1368F00D0F613 /* MTRInitializationExample.swift */, EAF14298296D561900E17793 /* CertTestView.swift */, EAF1429A296D57DF00E17793 /* CertTestViewModel.swift */, - 3CC0E8F92841DD3400EC6A18 /* TvCastingApp.swift */, 3CC0E8FB2841DD3400EC6A18 /* ContentView.swift */, 3C81C75228F8C79E001CB9D1 /* StartFromCacheView.swift */, 3C81C75428F8C7B6001CB9D1 /* StartFromCacheViewModel.swift */, @@ -236,6 +239,7 @@ 3C81C75928F8E42D001CB9D1 /* ConnectionViewModel.swift in Sources */, 3CA1CA7A28E281080023ED44 /* ClusterSelectorView.swift in Sources */, EAF14299296D561900E17793 /* CertTestView.swift in Sources */, + 3C69204A2AA1368F00D0F613 /* MTRInitializationExample.swift in Sources */, 3CCB8747286A5D0F00771BAD /* CommissioningView.swift in Sources */, 3CCB8748286A5D0F00771BAD /* CommissioningViewModel.swift in Sources */, 3CAC955B29BA948700BEA5C3 /* ExampleDAC.swift in Sources */, diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/xcshareddata/xcschemes/TvCasting Release.xcscheme b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/xcshareddata/xcschemes/TvCasting Release.xcscheme index bb32b8f700eee3..05333fbe6fe932 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/xcshareddata/xcschemes/TvCasting Release.xcscheme +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/xcshareddata/xcschemes/TvCasting Release.xcscheme @@ -50,6 +50,13 @@ ReferencedContainer = "container:TvCasting.xcodeproj"> + + + + + + + + DispatchQueue { + return DispatchQueue.main; + } + + func castingAppDidReceiveRequestForRotatingDeviceIdUniqueId(_ sender: Any) -> Data { + // dummy value, with at least 16 bytes (ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength), for demonstration only + return "0123456789ABCDEF".data(using: .utf8)! + } + + func castingAppDidReceiveRequestForCommissionableData(_ sender: Any) -> MTRCommissionableData { + // dummy values for demonstration only + return MTRCommissionableData( + passcode: 20202021, + discriminator: 3874, + spake2pIterationCount: 1000, + spake2pVerifier: nil, + spake2pSalt: nil) + } + + // dummy DAC values for demonstration only + let kDevelopmentDAC_Cert_FFF1_8001: Data = Data(base64Encoded: "MIIB5zCCAY6gAwIBAgIIac3xDenlTtEwCgYIKoZIzj0EAwIwPTElMCMGA1UEAwwcTWF0dGVyIERldiBQQUkgMHhGRkYxIG5vIFBJRDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwIBcNMjIwMjA1MDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMFMxJTAjBgNVBAMMHE1hdHRlciBEZXYgREFDIDB4RkZGMS8weDgwMDExFDASBgorBgEEAYKifAIBDARGRkYxMRQwEgYKKwYBBAGConwCAgwEODAwMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEY6xpNCkQoOVYj8b/Vrtj5i7M7LFI99TrA+5VJgFBV2fRalxmP3k+SRIyYLgpenzX58/HsxaznZjpDSk3dzjoKjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBSI3eezADgpMs/3NMBGJIEPRBaKbzAfBgNVHSMEGDAWgBRjVA5H9kscONE4hKRi0WwZXY/7PDAKBggqhkjOPQQDAgNHADBEAiABJ6J7S0RhDuL83E0reIVWNmC8D3bxchntagjfsrPBzQIga1ngr0Xz6yqFuRnTVzFSjGAoxBUjlUXhCOTlTnCXE1M=")!; + + let kDevelopmentDAC_PrivateKey_FFF1_8001: Data = Data(base64Encoded: "qrYAroroqrfXNifCF7fCBHCcppRq9fL3UwgzpStE+/8=")!; + + let kDevelopmentDAC_PublicKey_FFF1_8001: Data = Data(base64Encoded: "BEY6xpNCkQoOVYj8b/Vrtj5i7M7LFI99TrA+5VJgFBV2fRalxmP3k+SRIyYLgpenzX58/HsxaznZjpDSk3dzjoI=")!; + + let KPAI_FFF1_8000_Cert_Array: Data = Data(base64Encoded: "MIIByzCCAXGgAwIBAgIIVq2CIq2UW2QwCgYIKoZIzj0EAwIwMDEYMBYGA1UEAwwPTWF0dGVyIFRlc3QgUEFBMRQwEgYKKwYBBAGConwCAQwERkZGMTAgFw0yMjAyMDUwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowPTElMCMGA1UEAwwcTWF0dGVyIERldiBQQUkgMHhGRkYxIG5vIFBJRDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARBmpMVwhc+DIyHbQPM/JRIUmR/f+xeUIL0BZko7KiUxZQVEwmsYx5MsDOSr2hLC6+35ls7gWLC9Sv5MbjneqqCo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUY1QOR/ZLHDjROISkYtFsGV2P+zwwHwYDVR0jBBgwFoAUav0idx9RH+y/FkGXZxDc3DGhcX4wCgYIKoZIzj0EAwIDSAAwRQIhALLvJ/Sa6bUPuR7qyUxNC9u415KcbLiPrOUpNo0SBUwMAiBlXckrhr2QmIKmxiF3uCXX0F7b58Ivn+pxIg5+pwP4kQ==")!; + + let kCertificationDeclaration: Data = Data(base64Encoded: "MIICGQYJKoZIhvcNAQcCoIICCjCCAgYCAQMxDTALBglghkgBZQMEAgEwggFxBgkqhkiG9w0BBwGgggFiBIIBXhUkAAElAfH/NgIFAIAFAYAFAoAFA4AFBIAFBYAFBoAFB4AFCIAFCYAFCoAFC4AFDIAFDYAFDoAFD4AFEIAFEYAFEoAFE4AFFIAFFYAFFoAFF4AFGIAFGYAFGoAFG4AFHIAFHYAFHoAFH4AFIIAFIYAFIoAFI4AFJIAFJYAFJoAFJ4AFKIAFKYAFKoAFK4AFLIAFLYAFLoAFL4AFMIAFMYAFMoAFM4AFNIAFNYAFNoAFN4AFOIAFOYAFOoAFO4AFPIAFPYAFPoAFP4AFQIAFQYAFQoAFQ4AFRIAFRYAFRoAFR4AFSIAFSYAFSoAFS4AFTIAFTYAFToAFT4AFUIAFUYAFUoAFU4AFVIAFVYAFVoAFV4AFWIAFWYAFWoAFW4AFXIAFXYAFXoAFX4AFYIAFYYAFYoAFY4AYJAMWLAQTWklHMjAxNDJaQjMzMDAwMy0yNCQFACQGACUHlCYkCAAYMX0wewIBA4AUYvqCM1ms+qmWPhz6FArd9QTzcWAwCwYJYIZIAWUDBAIBMAoGCCqGSM49BAMCBEcwRQIgJOXR9Hp9ew0gaibvaZt8l1e3LUaQid4xkuZ4x0Xn9gwCIQD4qi+nEfy3m5fjl87aZnuuRk4r0//fw8zteqjKX0wafA==")!; + func castingAppDidReceiveRequestForDeviceAttestationCredentials(_ sender: Any) -> MTRDeviceAttestationCredentials { + return MTRDeviceAttestationCredentials( + certificationDeclaration: kCertificationDeclaration, + firmwareInformation: Data(), + deviceAttestationCert: kDevelopmentDAC_Cert_FFF1_8001, + productAttestationIntermediateCert: KPAI_FFF1_8000_Cert_Array) + } + + func castingApp(_ sender: Any, didReceiveRequestToSignCertificateRequest csrData: Data) -> Data { + var privateKey = Data() + privateKey.append(kDevelopmentDAC_PublicKey_FFF1_8001); + privateKey.append(kDevelopmentDAC_PrivateKey_FFF1_8001); + + let privateKeyRef: SecKey = SecKeyCreateWithData(privateKey as NSData, + [ + kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, + kSecAttrKeyClass: kSecAttrKeyClassPrivate, + kSecAttrKeySizeInBits: 256 + ] as NSDictionary, nil)! + + let _:Unmanaged = Unmanaged.passRetained(privateKeyRef); + + return Data() // TODO: use SecKey above to sign csrData and return resulting value + } +} + +class MTRInitializationExample { + let Log = Logger(subsystem: "com.matter.casting", + category: "MTRInitializationExample") + + func initialize() -> MatterError { + if let castingApp = MTRCastingApp.getSharedInstance() + { + return castingApp.initialize(with: MTRAppParametersDataSource()) + } + else + { + return MATTER_ERROR_INCORRECT_STATE + } + } +} diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift index f0d67cacee9cd5..2616ec0714f537 100644 --- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift +++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift @@ -29,50 +29,90 @@ struct TvCastingApp: App { WindowGroup { ContentView() .onAppear(perform: { - if let castingServerBridge = CastingServerBridge.getSharedInstance() + if ProcessInfo.processInfo.environment["CHIP_CASTING_SIMPLIFIED"] == "1" { - let appParameters: AppParameters = AppParameters() + self.Log.info("CHIP_CASTING_SIMPLIFIED = 1") - var rotatingDeviceIdUniqueId: [UInt8] = [UInt8](repeating: 0, count: 16 ) - for i in (0...15) + let err: MatterError = MTRInitializationExample().initialize() + if !MATTER_NO_ERROR.isEqual(err) { - rotatingDeviceIdUniqueId[i] = UInt8.random(in: 0..<255) + self.Log.error("CastingApp initialization failed \(err)") + } + } + else + { + self.Log.info("CHIP_CASTING_SIMPLIFIED = 0") + + if let castingServerBridge = CastingServerBridge.getSharedInstance() + { + let appParameters: AppParameters = AppParameters() + + var rotatingDeviceIdUniqueId: [UInt8] = [UInt8](repeating: 0, count: 16 ) + for i in (0...15) + { + rotatingDeviceIdUniqueId[i] = UInt8.random(in: 0..<255) + } + appParameters.rotatingDeviceIdUniqueId = Data(rotatingDeviceIdUniqueId) + + let onboardingParameters: OnboardingPayload = OnboardingPayload() + onboardingParameters.setupPasscode = 20202021 + onboardingParameters.setupDiscriminator = 3840 + + appParameters.onboardingPayload = onboardingParameters + + let err = castingServerBridge.initializeApp(appParameters, clientQueue: DispatchQueue.main, initAppStatusHandler: { (result: Bool) -> () in + self.Log.info("initializeApp result \(result)") + }) + self.Log.info("initializeApp return value \(err)") } - appParameters.rotatingDeviceIdUniqueId = Data(rotatingDeviceIdUniqueId) - - let onboardingParameters: OnboardingPayload = OnboardingPayload() - onboardingParameters.setupPasscode = 20202021 - onboardingParameters.setupDiscriminator = 3840 - - appParameters.onboardingPayload = onboardingParameters - - let err = castingServerBridge.initializeApp(appParameters, clientQueue: DispatchQueue.main, initAppStatusHandler: { (result: Bool) -> () in - self.Log.info("initializeApp result \(result)") - }) - self.Log.info("initializeApp return value \(err)") } }) .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in self.Log.info("TvCastingApp: UIApplication.willResignActiveNotification") - if let castingServerBridge = CastingServerBridge.getSharedInstance() + if ProcessInfo.processInfo.environment["CHIP_CASTING_SIMPLIFIED"] == "1" + { + if let castingApp = MTRCastingApp.getSharedInstance() + { + let err: MatterError = castingApp.stop() + if !MATTER_NO_ERROR.isEqual(err) + { + self.Log.error("CastingApp stop failed \(err)") + } + } + } + else if let castingServerBridge = CastingServerBridge.getSharedInstance() { castingServerBridge.stopMatterServer() } } .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in self.Log.info("TvCastingApp: UIApplication.didBecomeActiveNotification") - if(!firstAppActivation) + if ProcessInfo.processInfo.environment["CHIP_CASTING_SIMPLIFIED"] == "1" { - if let castingServerBridge = CastingServerBridge.getSharedInstance() + if let castingApp = MTRCastingApp.getSharedInstance() { - castingServerBridge.startMatterServer(DispatchQueue.main, startMatterServerCompletionCallback: { (error: MatterError) -> () in - DispatchQueue.main.async { - self.Log.info("TvCastingApp.startMatterServerCompletionCallback called with \(error)") - } - }) + let err: MatterError = castingApp.start() + if !MATTER_NO_ERROR.isEqual(err) + { + self.Log.error("CastingApp start failed \(err)") + } + } + } + else + { + if(!firstAppActivation) + { + if let castingServerBridge = CastingServerBridge.getSharedInstance() + { + castingServerBridge.startMatterServer(DispatchQueue.main, startMatterServerCompletionCallback: { (error: MatterError) -> () in + DispatchQueue.main.async { + self.Log.info("TvCastingApp.startMatterServerCompletionCallback called with \(error)") + } + }) + } } + firstAppActivation = false } - firstAppActivation = false } .onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in self.Log.info("TvCastingApp: UIApplication.didEnterBackgroundNotification") diff --git a/examples/tv-casting-app/darwin/args.gni b/examples/tv-casting-app/darwin/args.gni index 6a8033ab8ac9d0..1158e98e5f2d99 100644 --- a/examples/tv-casting-app/darwin/args.gni +++ b/examples/tv-casting-app/darwin/args.gni @@ -20,8 +20,10 @@ chip_device_project_config_include = "" chip_project_config_include = "" chip_system_project_config_include = "" -chip_project_config_include_dirs += - [ "${chip_root}/examples/tv-casting-app/tv-casting-common/include" ] +chip_project_config_include_dirs += [ + "${chip_root}/examples/tv-casting-app/tv-casting-common/include", + "${chip_root}/examples/tv-casting-app/tv-casting-common", +] chip_project_config_include_dirs += [ "${chip_root}/config/ios" ] chip_build_libshell = true diff --git a/examples/tv-casting-app/tv-casting-common/BUILD.gn b/examples/tv-casting-app/tv-casting-common/BUILD.gn index 8292d8366b06da..115a0b7e4bbfb0 100644 --- a/examples/tv-casting-app/tv-casting-common/BUILD.gn +++ b/examples/tv-casting-app/tv-casting-common/BUILD.gn @@ -111,8 +111,10 @@ chip_data_model("tv-casting-common") { public_configs = [ ":config" ] - include_dirs = - [ "${chip_root}/examples/tv-casting-app/tv-casting-common/include" ] + include_dirs = [ + "${chip_root}/examples/tv-casting-app/tv-casting-common/include", + "${chip_root}/examples/tv-casting-app/tv-casting-common", + ] is_server = true } diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingApp.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingApp.cpp index 3dd42d91d293bb..f8d66b03e0ac0c 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingApp.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CastingApp.cpp @@ -60,9 +60,17 @@ CHIP_ERROR CastingApp::Initialize(const AppParameters & appParameters) #if CHIP_ENABLE_ROTATING_DEVICE_ID MutableByteSpanDataProvider * uniqueIdProvider = appParameters.GetRotatingDeviceIdUniqueIdProvider(); - if (uniqueIdProvider != nullptr && uniqueIdProvider->Get() != nullptr) + if (uniqueIdProvider != nullptr) { - ReturnErrorOnFailure(chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(*uniqueIdProvider->Get())); + chip::MutableByteSpan * uniqueId = uniqueIdProvider->Get(); + if (uniqueId != nullptr) + { + ReturnErrorOnFailure(chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(*uniqueId)); + } + else + { + return CHIP_ERROR_INVALID_ARGUMENT; + } } #endif // CHIP_ENABLE_ROTATING_DEVICE_ID