From 63c470921de6dc6e271bc19718466088a62f5350 Mon Sep 17 00:00:00 2001 From: Philip Gregor <147669098+pgregorr-amazon@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:09:55 -0700 Subject: [PATCH] v1.3 Commissioner Passcode field for Linux and Android tv-casting-apps (#33038) --- .../com/matter/casting/DiscoveryExampleFragment.java | 4 ++++ .../jni/com/matter/casting/core/CastingPlayer.java | 2 ++ .../com/matter/casting/core/MatterCastingPlayer.java | 11 ++++++++++- .../app/src/main/jni/cpp/support/Converters-JNI.cpp | 5 +++-- examples/tv-casting-app/linux/simple-app-helper.cpp | 3 ++- .../tv-casting-common/core/CastingPlayer.cpp | 3 +++ .../tv-casting-common/core/CastingPlayer.h | 5 ++++- .../tv-casting-common/core/CastingPlayerDiscovery.cpp | 11 ++++++----- .../tv-casting-common/support/CastingStore.cpp | 10 ++++++++++ .../tv-casting-common/support/CastingStore.h | 2 ++ src/lib/dnssd/TxtFields.cpp | 4 ++-- src/lib/dnssd/Types.h | 8 +++----- src/lib/dnssd/tests/TestTxtFields.cpp | 8 ++++---- 13 files changed, 55 insertions(+), 21 deletions(-) diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java index 49076867a9cc75..a706780c5be3b4 100644 --- a/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java +++ b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java @@ -350,6 +350,10 @@ private String getCastingPlayerButtonText(CastingPlayer player) { ? (aux.isEmpty() ? "" : ", ") + "Device Type: " + player.getDeviceType() : ""; aux += (aux.isEmpty() ? "" : ", ") + "Resolved IP?: " + (player.getIpAddresses().size() > 0); + aux += + (aux.isEmpty() ? "" : ", ") + + "Supports Commissioner Generated Passcode: " + + (player.getSupportsCommissionerGeneratedPasscode()); aux = aux.isEmpty() ? aux : "\n" + aux; return main + aux; diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java index 39db6488fa8ed8..3c3a74032bd313 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/CastingPlayer.java @@ -49,6 +49,8 @@ public interface CastingPlayer { long getDeviceType(); + boolean getSupportsCommissionerGeneratedPasscode(); + List getEndpoints(); @Override diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java index dd4bd0ba6531c6..a4f03a00e4f5a2 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/matter/casting/core/MatterCastingPlayer.java @@ -47,6 +47,8 @@ public class MatterCastingPlayer implements CastingPlayer { private int productId; private int vendorId; private long deviceType; + private boolean supportsCommissionerGeneratedPasscode; + protected long _cppCastingPlayer; public MatterCastingPlayer( @@ -59,7 +61,8 @@ public MatterCastingPlayer( int port, int productId, int vendorId, - long deviceType) { + long deviceType, + boolean supportsCommissionerGeneratedPasscode) { this.connected = connected; this.deviceId = deviceId; this.hostName = hostName; @@ -70,6 +73,7 @@ public MatterCastingPlayer( this.productId = productId; this.vendorId = vendorId; this.deviceType = deviceType; + this.supportsCommissionerGeneratedPasscode = supportsCommissionerGeneratedPasscode; } /** @@ -131,6 +135,11 @@ public long getDeviceType() { return this.deviceType; } + @Override + public boolean getSupportsCommissionerGeneratedPasscode() { + return this.supportsCommissionerGeneratedPasscode; + } + @Override public native List getEndpoints(); diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/Converters-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/Converters-JNI.cpp index aa5ef2b25f0096..00ca47216ae804 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/Converters-JNI.cpp +++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/support/Converters-JNI.cpp @@ -151,7 +151,7 @@ jobject convertCastingPlayerFromCppToJava(matter::casting::memory::StrongGetMethodID(matterCastingPlayerJavaClass, "", - "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;IIIJ)V"); + "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;IIIJZ)V"); if (constructor == nullptr) { ChipLogError(AppServer, "convertCastingPlayerFromCppToJava() could not locate MatterCastingPlayer Java class constructor"); @@ -186,7 +186,8 @@ jobject convertCastingPlayerFromCppToJava(matter::casting::memory::StrongNewStringUTF(player->GetId()), env->NewStringUTF(player->GetHostName()), env->NewStringUTF(player->GetDeviceName()), env->NewStringUTF(player->GetInstanceName()), jIpAddressList, (jint) (player->GetPort()), (jint) (player->GetProductId()), - (jint) (player->GetVendorId()), (jlong) (player->GetDeviceType())); + (jint) (player->GetVendorId()), (jlong) (player->GetDeviceType()), + static_cast(player->GetSupportsCommissionerGeneratedPasscode())); if (jMatterCastingPlayer == nullptr) { ChipLogError(AppServer, "convertCastingPlayerFromCppToJava(): Could not create MatterCastingPlayer Java object"); diff --git a/examples/tv-casting-app/linux/simple-app-helper.cpp b/examples/tv-casting-app/linux/simple-app-helper.cpp index d89b5c25234efc..de8c255366cd37 100644 --- a/examples/tv-casting-app/linux/simple-app-helper.cpp +++ b/examples/tv-casting-app/linux/simple-app-helper.cpp @@ -45,6 +45,7 @@ DiscoveryDelegateImpl * DiscoveryDelegateImpl::GetInstance() void DiscoveryDelegateImpl::HandleOnAdded(matter::casting::memory::Strong player) { + ChipLogProgress(AppServer, "DiscoveryDelegateImpl::HandleOnAdded() called"); if (commissionersCount == 0) { ChipLogProgress(AppServer, "Select discovered Casting Player (start index = 0) to request commissioning"); @@ -58,7 +59,7 @@ void DiscoveryDelegateImpl::HandleOnAdded(matter::casting::memory::Strong player) { - ChipLogProgress(AppServer, "Updated CastingPlayer with ID: %s", player->GetId()); + ChipLogProgress(AppServer, "DiscoveryDelegateImpl::HandleOnUpdated() Updated CastingPlayer with ID: %s", player->GetId()); } void InvokeContentLauncherLaunchURL(matter::casting::memory::Strong endpoint) diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp index fe966722ccf902..c9f938dbc695c7 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp @@ -236,6 +236,7 @@ bool CastingPlayer::ContainsDesiredEndpoint(core::CastingPlayer * cachedCastingP void CastingPlayer::LogDetail() const { + ChipLogProgress(AppServer, "CastingPlayer::LogDetail() called"); if (strlen(mAttributes.id) != 0) { ChipLogDetail(AppServer, "\tID: %s", mAttributes.id); @@ -281,6 +282,8 @@ void CastingPlayer::LogDetail() const { ChipLogDetail(AppServer, "\tDevice Type: %" PRIu32, mAttributes.deviceType); } + ChipLogDetail(AppServer, "\tSupports Commissioner Generated Passcode: %s", + mAttributes.supportsCommissionerGeneratedPasscode ? "true" : "false"); if (mAttributes.nodeId > 0) { ChipLogDetail(AppServer, "\tNode ID: 0x" ChipLogFormatX64, ChipLogValueX64(mAttributes.nodeId)); diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h index 7d383bb6669225..783d50f60af390 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h @@ -56,13 +56,14 @@ class CastingPlayerAttributes char deviceName[chip::Dnssd::kMaxDeviceNameLen + 1] = {}; char hostName[chip::Dnssd::kHostNameMaxLength + 1] = {}; char instanceName[chip::Dnssd::Commission::kInstanceNameMaxLength + 1] = {}; - unsigned int numIPs; // number of valid IP addresses + unsigned int numIPs; // Number of valid IP addresses chip::Inet::IPAddress ipAddresses[chip::Dnssd::CommonResolutionData::kMaxIPAddresses]; chip::Inet::InterfaceId interfaceId; uint16_t port; uint16_t productId; uint16_t vendorId; uint32_t deviceType; + bool supportsCommissionerGeneratedPasscode; chip::NodeId nodeId = 0; chip::FabricIndex fabricIndex = 0; @@ -182,6 +183,8 @@ class CastingPlayer : public std::enable_shared_from_this uint32_t GetDeviceType() const { return mAttributes.deviceType; } + bool GetSupportsCommissionerGeneratedPasscode() const { return mAttributes.supportsCommissionerGeneratedPasscode; } + chip::NodeId GetNodeId() const { return mAttributes.nodeId; } chip::FabricIndex GetFabricIndex() const { return mAttributes.fabricIndex; } diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp index 9b26a868efd8c1..9dd365d8db559f 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp @@ -93,11 +93,12 @@ void DeviceDiscoveryDelegateImpl::OnDiscoveredDevice(const chip::Dnssd::Discover { attributes.ipAddresses[j] = nodeData.resolutionData.ipAddress[j]; } - attributes.interfaceId = nodeData.resolutionData.interfaceId; - attributes.port = nodeData.resolutionData.port; - attributes.productId = nodeData.nodeData.productId; - attributes.vendorId = nodeData.nodeData.vendorId; - attributes.deviceType = nodeData.nodeData.deviceType; + attributes.interfaceId = nodeData.resolutionData.interfaceId; + attributes.port = nodeData.resolutionData.port; + attributes.productId = nodeData.nodeData.productId; + attributes.vendorId = nodeData.nodeData.vendorId; + attributes.deviceType = nodeData.nodeData.deviceType; + attributes.supportsCommissionerGeneratedPasscode = nodeData.nodeData.supportsCommissionerGeneratedPasscode; memory::Strong player = std::make_shared(attributes); diff --git a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp index c9b9c5450b3641..819c0299945ed4 100644 --- a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp +++ b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp @@ -182,6 +182,14 @@ std::vector CastingStore::ReadAll() continue; } + if (castingPlayerContainerTagNum == kCastingPlayerSupportsCommissionerGeneratedPasscodeTag) + { + err = reader.Get(attributes.supportsCommissionerGeneratedPasscode); + VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format())); + continue; + } + if (castingPlayerContainerTagNum == kCastingPlayerPortTag) { err = reader.Get(attributes.port); @@ -472,6 +480,8 @@ CHIP_ERROR CastingStore::WriteAll(std::vector castingPlayer ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerVendorIdTag), castingPlayer.GetVendorId())); ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerProductIdTag), castingPlayer.GetProductId())); ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerDeviceTypeIdTag), castingPlayer.GetDeviceType())); + ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerSupportsCommissionerGeneratedPasscodeTag), + castingPlayer.GetSupportsCommissionerGeneratedPasscode())); ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerPortTag), castingPlayer.GetPort())); ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerInstanceNameTag), (const uint8_t *) castingPlayer.GetInstanceName(), diff --git a/examples/tv-casting-app/tv-casting-common/support/CastingStore.h b/examples/tv-casting-app/tv-casting-common/support/CastingStore.h index 9602af892c9909..c60fa128079122 100644 --- a/examples/tv-casting-app/tv-casting-common/support/CastingStore.h +++ b/examples/tv-casting-app/tv-casting-common/support/CastingStore.h @@ -97,6 +97,8 @@ class CastingStore : public chip::FabricTable::Delegate kCastingPlayerEndpointServerListContainerTag, kCastingPlayerEndpointServerClusterIdTag, + kCastingPlayerSupportsCommissionerGeneratedPasscodeTag, + kContextTagMaxNum = UINT8_MAX }; diff --git a/src/lib/dnssd/TxtFields.cpp b/src/lib/dnssd/TxtFields.cpp index b77d991784867d..c4ec70e342d41a 100644 --- a/src/lib/dnssd/TxtFields.cpp +++ b/src/lib/dnssd/TxtFields.cpp @@ -185,7 +185,7 @@ void GetPairingInstruction(const ByteSpan & value, char * pairingInstruction) uint8_t GetCommissionerPasscode(const ByteSpan & value) { - return MakeU8FromAsciiDecimal(value); + return MakeBoolFromAsciiDecimal(value); } Optional GetRetryInterval(const ByteSpan & value) @@ -256,7 +256,7 @@ void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & val, DnssdNodeDa nodeData.pairingHint = Internal::GetPairingHint(val); break; case TxtFieldKey::kCommissionerPasscode: - nodeData.commissionerPasscode = Internal::GetCommissionerPasscode(val); + nodeData.supportsCommissionerGeneratedPasscode = Internal::GetCommissionerPasscode(val); break; default: break; diff --git a/src/lib/dnssd/Types.h b/src/lib/dnssd/Types.h index 15dbf90670ac34..43e55bfbc65e0e 100644 --- a/src/lib/dnssd/Types.h +++ b/src/lib/dnssd/Types.h @@ -214,7 +214,7 @@ struct DnssdNodeData uint16_t productId = 0; uint16_t pairingHint = 0; uint8_t commissioningMode = 0; - uint8_t commissionerPasscode = 0; + bool supportsCommissionerGeneratedPasscode = false; uint8_t rotatingId[kMaxRotatingIdLen] = {}; char instanceName[Commission::kInstanceNameMaxLength + 1] = {}; char deviceName[kMaxDeviceNameLen + 1] = {}; @@ -272,10 +272,8 @@ struct DnssdNodeData ChipLogDetail(Discovery, "\tInstance Name: %s", instanceName); } ChipLogDetail(Discovery, "\tCommissioning Mode: %u", commissioningMode); - if (commissionerPasscode > 0) - { - ChipLogDetail(Discovery, "\tCommissioner Passcode: %u", commissionerPasscode); - } + ChipLogDetail(Discovery, "\tSupports Commissioner Generated Passcode: %s", + supportsCommissionerGeneratedPasscode ? "true" : "false"); } }; diff --git a/src/lib/dnssd/tests/TestTxtFields.cpp b/src/lib/dnssd/tests/TestTxtFields.cpp index 4593a4903b1a01..d6e7e6ea240670 100644 --- a/src/lib/dnssd/tests/TestTxtFields.cpp +++ b/src/lib/dnssd/tests/TestTxtFields.cpp @@ -309,7 +309,7 @@ bool NodeDataIsEmpty(const DiscoveredNodeData & node) node.nodeData.pairingHint != 0 || node.resolutionData.mrpRetryIntervalIdle.HasValue() || node.resolutionData.mrpRetryIntervalActive.HasValue() || node.resolutionData.mrpRetryActiveThreshold.HasValue() || node.resolutionData.isICDOperatingAsLIT.HasValue() || node.resolutionData.supportsTcp || - node.nodeData.commissionerPasscode != 0) + node.nodeData.supportsCommissionerGeneratedPasscode != 0) { return false; } @@ -360,12 +360,12 @@ void TestFillDiscoveredNodeDataFromTxt(nlTestSuite * inSuite, void * inContext) filled.nodeData.commissioningMode = 0; NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); - // Commissioning mode + // Supports Commissioner Generated Passcode strcpy(key, "CP"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled.nodeData); - NL_TEST_ASSERT(inSuite, filled.nodeData.commissionerPasscode == 1); - filled.nodeData.commissionerPasscode = 0; + NL_TEST_ASSERT(inSuite, filled.nodeData.supportsCommissionerGeneratedPasscode == true); + filled.nodeData.supportsCommissionerGeneratedPasscode = false; NL_TEST_ASSERT(inSuite, NodeDataIsEmpty(filled)); // Device type