From f36bda1db68d5abbd0db23e6bfdfbbf2b51449e5 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Tue, 31 May 2022 18:57:23 -0700 Subject: [PATCH 01/12] Add text entries to mDNS service discovery response --- .../android/AndroidChipPlatform-JNI.cpp | 6 +- src/platform/android/DnssdImpl.cpp | 95 ++++++++++++++++++- src/platform/android/DnssdImpl.h | 3 +- .../java/chip/platform/ChipMdnsCallback.java | 3 + .../chip/platform/ChipMdnsCallbackImpl.java | 11 +++ .../platform/NsdManagerServiceResolver.java | 38 +++++++- 6 files changed, 148 insertions(+), 8 deletions(-) diff --git a/src/platform/android/AndroidChipPlatform-JNI.cpp b/src/platform/android/AndroidChipPlatform-JNI.cpp index 021849256df7b4..2b8450d23b1f6c 100644 --- a/src/platform/android/AndroidChipPlatform-JNI.cpp +++ b/src/platform/android/AndroidChipPlatform-JNI.cpp @@ -238,11 +238,11 @@ JNI_METHOD(void, nativeSetServiceResolver)(JNIEnv * env, jclass self, jobject re } JNI_MDNSCALLBACK_METHOD(void, handleServiceResolve) -(JNIEnv * env, jclass self, jstring instanceName, jstring serviceType, jstring address, jint port, jlong callbackHandle, - jlong contextHandle) +(JNIEnv * env, jclass self, jstring instanceName, jstring serviceType, jstring address, jint port, jobject attributes, + jlong callbackHandle, jlong contextHandle) { using ::chip::Dnssd::HandleResolve; - HandleResolve(instanceName, serviceType, address, port, callbackHandle, contextHandle); + HandleResolve(instanceName, serviceType, address, port, attributes, callbackHandle, contextHandle); } #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index 0fa4397d8f39ad..806ae5ae215322 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -29,6 +29,7 @@ #include #include +#include #include namespace chip { @@ -40,6 +41,9 @@ namespace { jobject sResolverObject = nullptr; jobject sMdnsCallbackObject = nullptr; jmethodID sResolveMethod = nullptr; +jmethodID sGetAttributeKeysMethod = nullptr; +jmethodID sGetAttributeDataMethod = nullptr; +jclass sMdnsCallbackClass = nullptr; jmethodID sPublishMethod = nullptr; jmethodID sRemoveServicesMethod = nullptr; } // namespace @@ -185,9 +189,14 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) sResolverObject = env->NewGlobalRef(resolverObject); sMdnsCallbackObject = env->NewGlobalRef(mdnsCallbackObject); jclass resolverClass = env->GetObjectClass(sResolverObject); + sMdnsCallbackClass = env->GetObjectClass(sMdnsCallbackObject); VerifyOrReturn(resolverClass != nullptr, ChipLogError(Discovery, "Failed to get Resolver Java class")); + sGetAttributeKeysMethod = env->GetMethodID(sMdnsCallbackClass, "getAttributeKeys", "(Ljava/util/Map;)[Ljava/lang/String;"); + + sGetAttributeDataMethod = env->GetMethodID(sMdnsCallbackClass, "getAttributeData", "(Ljava/util/Map;Ljava/lang/String;)[B"); + sResolveMethod = env->GetMethodID(resolverClass, "resolve", "(Ljava/lang/String;Ljava/lang/String;JJLchip/platform/ChipMdnsCallback;)V"); if (sResolveMethod == nullptr) @@ -196,6 +205,18 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) env->ExceptionClear(); } + if (sGetAttributeKeysMethod == nullptr) + { + ChipLogError(Discovery, "Failed to access MdnsCallback 'getAttributeKeys' method"); + env->ExceptionClear(); + } + + if (sGetAttributeDataMethod == nullptr) + { + ChipLogError(Discovery, "Failed to access MdnsCallback 'getAttributeData' method"); + env->ExceptionClear(); + } + sPublishMethod = env->GetMethodID(resolverClass, "publish", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;[[B[Ljava/lang/String;)V"); @@ -213,7 +234,8 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) } } -void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jlong callbackHandle, jlong contextHandle) +void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject attributes, jlong callbackHandle, + jlong contextHandle) { VerifyOrReturn(callbackHandle != 0, ChipLogError(Discovery, "HandleResolve called with callback equal to nullptr")); @@ -243,7 +265,78 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j CopyString(service.mType, jniServiceType.c_str()); service.mPort = static_cast(port); + if (attributes != nullptr) + { + jobjectArray keys = (jobjectArray) env->CallObjectMethod(sMdnsCallbackObject, sGetAttributeKeysMethod, attributes); + size_t size = env->GetArrayLength(keys); + TextEntry * entries = new TextEntry[size]; + for (size_t i = 0; i < size; i++) + { + jstring jniKeyObject = (jstring) env->GetObjectArrayElement(keys, i); + entries[i].mKey = getTxtInfoKey(env, jniKeyObject); + + jbyteArray datas = + (jbyteArray) env->CallObjectMethod(sMdnsCallbackObject, sGetAttributeDataMethod, attributes, jniKeyObject); + if (datas != nullptr) + { + size_t dataSize = env->GetArrayLength(datas); + uint8_t * data = new uint8_t[dataSize + 1]; + jbyte * jnidata = env->GetByteArrayElements(datas, nullptr); + for (size_t j = 0; j < dataSize; j++) + { + data[j] = (uint8_t) jnidata[j]; + } + entries[i].mDataSize = dataSize; + entries[i].mData = data; + ChipLogProgress(Discovery, " ----- entry [%u] : %s %s\n", static_cast(i), entries[i].mKey, + (char *) (entries[i].mData)); + } + else + { + ChipLogProgress(Discovery, " ----- key=%s", entries[i].mKey); + + entries[i].mDataSize = 0; + entries[i].mData = nullptr; + } + } + service.mTextEntrySize = size; + service.mTextEntries = entries; + } + else + { + ChipLogError(Discovery, "attributes is null"); + service.mTextEntrySize = 0; + service.mTextEntries = nullptr; + } + dispatch(CHIP_NO_ERROR, &service, &ipAddress); + + if (service.mTextEntries != nullptr) + { + size_t size = service.mTextEntrySize; + for (size_t i = 0; i < size; i++) + { + if (service.mTextEntries[i].mData != nullptr) + { + delete[] service.mTextEntries[i].mData; + } + } + delete[] service.mTextEntries; + } +} + +const char * getTxtInfoKey(JNIEnv * env, jstring key) +{ + const char * keyList[] = { "D", "VP", "AP", "CM", "DT", "DN", "RI", "PI", "PH", "CRI", "CRA", "T" }; + JniUtfString jniKey(env, key); + for (auto & info : keyList) + { + if (strcmp(info, jniKey.c_str()) == 0) + { + return info; + } + } + return ""; } } // namespace Dnssd diff --git a/src/platform/android/DnssdImpl.h b/src/platform/android/DnssdImpl.h index 0a6b30870b081b..7b40976e91f211 100644 --- a/src/platform/android/DnssdImpl.h +++ b/src/platform/android/DnssdImpl.h @@ -32,8 +32,9 @@ void InitializeWithObjects(jobject resolverObject, jobject chipMdnsCallbackObjec /** * Pass results of the service resolution to the CHIP stack. */ -void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jlong callbackHandle, +void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject attributes, jlong callbackHandle, jlong contextHandle); +const char * getTxtInfoKey(JNIEnv * env, jstring key); } // namespace Dnssd } // namespace chip diff --git a/src/platform/android/java/chip/platform/ChipMdnsCallback.java b/src/platform/android/java/chip/platform/ChipMdnsCallback.java index 58304997a07ef4..3249c18cedb59f 100644 --- a/src/platform/android/java/chip/platform/ChipMdnsCallback.java +++ b/src/platform/android/java/chip/platform/ChipMdnsCallback.java @@ -17,6 +17,8 @@ */ package chip.platform; +import java.util.Map; + /** Interface for communicating with the CHIP mDNS stack. */ public interface ChipMdnsCallback { void handleServiceResolve( @@ -24,6 +26,7 @@ void handleServiceResolve( String serviceType, String address, int port, + Map attributes, long callbackHandle, long contextHandle); } diff --git a/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java b/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java index b57189994dab58..c20d0d496b019a 100644 --- a/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java +++ b/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java @@ -17,12 +17,23 @@ */ package chip.platform; +import java.util.Map; + public class ChipMdnsCallbackImpl implements ChipMdnsCallback { public native void handleServiceResolve( String instanceName, String serviceType, String address, int port, + Map attributes, long callbackHandle, long contextHandle); + + public String[] getAttributeKeys(Map attributes) { + return attributes.keySet().toArray(new String[attributes.size()]); + } + + public byte[] getAttributeData(Map attributes, String key) { + return attributes.get(key); + } } diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index 63a28d3ffd5a8e..46786cb0777bc7 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -26,11 +26,14 @@ import android.os.Looper; import android.util.Log; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class NsdManagerServiceResolver implements ServiceResolver { private static final String TAG = NsdManagerServiceResolver.class.getSimpleName(); private static final long RESOLVE_SERVICE_TIMEOUT = 30000; + private static final long RESOLVE_SERVICE_FOUND = 3000; private final NsdManager nsdManager; private MulticastLock multicastLock; private Handler mainThreadHandler; @@ -58,7 +61,7 @@ public void resolve( NsdServiceInfo serviceInfo = new NsdServiceInfo(); serviceInfo.setServiceName(instanceName); serviceInfo.setServiceType(serviceType); - Log.d(TAG, "Starting service resolution for '" + instanceName + "'"); + Log.d(TAG, "resolve: Starting service resolution for '" + instanceName + "' type '"+serviceType+"'"); Runnable timeoutRunnable = new Runnable() { @@ -67,12 +70,38 @@ public void run() { // Ensure we always release the multicast lock. It's possible that we release the // multicast lock here before ResolveListener returns, but since NsdManager has no API // to cancel service resolution, there's not much we can do here. + Log.d(TAG, "resolve: Timing out"); if (multicastLock.isHeld()) { multicastLock.release(); } } }; + // TODO: remove this hack before merge + Runnable hack = + new Runnable() { + @Override + public void run() { + + Map attributes = new HashMap(); + attributes.put("VP", "65521+123".getBytes()); + attributes.put("RI", new byte[] { (byte)0xe0, (byte)0x4f, (byte)0xd0, + 0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b, + 0x30, 0x30, (byte)0x9d}); + attributes.put("DN", "Chris iPhone".getBytes()); + + Log.d(TAG, "resolve: Hacking service resolution for '" + instanceName + "' type '"+serviceType+"'"); + chipMdnsCallback.handleServiceResolve( + instanceName, + serviceType, + "10.0.2.2", + 5540, + attributes, + callbackHandle, + contextHandle); + } + }; + this.nsdManager.resolveService( serviceInfo, new NsdManager.ResolveListener() { @@ -82,7 +111,7 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { TAG, "Failed to resolve service '" + serviceInfo.getServiceName() + "': " + errorCode); chipMdnsCallback.handleServiceResolve( - instanceName, serviceType, null, 0, callbackHandle, contextHandle); + instanceName, serviceType, null, 0, null, callbackHandle, contextHandle); if (multicastLock.isHeld()) { multicastLock.release(); @@ -91,7 +120,7 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { } @Override - public void onServiceResolved(NsdServiceInfo serviceInfo) { + public void onServiceResolved(NsdServiceInfo serviceInfo) { Log.i( TAG, "Resolved service '" @@ -104,6 +133,7 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { serviceType, serviceInfo.getHost().getHostAddress(), serviceInfo.getPort(), + serviceInfo.getAttributes(), callbackHandle, contextHandle); @@ -114,6 +144,8 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { } }); mainThreadHandler.postDelayed(timeoutRunnable, RESOLVE_SERVICE_TIMEOUT); + + mainThreadHandler.postDelayed(hack, RESOLVE_SERVICE_FOUND); } @Override From 188134a3cc204de0df21ad77ae40c74814ddd1c5 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Tue, 31 May 2022 19:31:45 -0700 Subject: [PATCH 02/12] fix android tv-app build --- .../com/matter/tv/server/MatterCommissioningPrompter.java | 6 +----- .../java/src/com/tcl/chip/tvapp/UserPrompterResolver.java | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java index 4be7f24903f1cd..fc284d8957d99f 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java @@ -114,11 +114,7 @@ public void promptCommissioningSucceeded(int vendorId, int productId, String com public void promptCommissioningFailed(String commissioneeName, String error) { Log.d( TAG, - "Received prompt for failure vendor id:" - + vendorId - + " productId:" - + productId - + ". Commissionee: " + "Received prompt for failure Commissionee: " + commissioneeName); NotificationCompat.Builder builder = new NotificationCompat.Builder(activity, CHANNEL_ID) diff --git a/examples/tv-app/android/java/src/com/tcl/chip/tvapp/UserPrompterResolver.java b/examples/tv-app/android/java/src/com/tcl/chip/tvapp/UserPrompterResolver.java index 18c0bd181de770..b3a0ca5f6ed77f 100644 --- a/examples/tv-app/android/java/src/com/tcl/chip/tvapp/UserPrompterResolver.java +++ b/examples/tv-app/android/java/src/com/tcl/chip/tvapp/UserPrompterResolver.java @@ -19,7 +19,7 @@ public class UserPrompterResolver { - private static final String TAG = "UserPrompterResolver"; + protected static final String TAG = "UserPrompterResolver"; public native void OnPinCodeEntered(int pinCode); From f75fcca98b57e928269064d74acb56d51b6816e6 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Tue, 31 May 2022 19:47:11 -0700 Subject: [PATCH 03/12] remove hack --- .../platform/NsdManagerServiceResolver.java | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index 46786cb0777bc7..387c93521be274 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -77,31 +77,6 @@ public void run() { } }; - // TODO: remove this hack before merge - Runnable hack = - new Runnable() { - @Override - public void run() { - - Map attributes = new HashMap(); - attributes.put("VP", "65521+123".getBytes()); - attributes.put("RI", new byte[] { (byte)0xe0, (byte)0x4f, (byte)0xd0, - 0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b, - 0x30, 0x30, (byte)0x9d}); - attributes.put("DN", "Chris iPhone".getBytes()); - - Log.d(TAG, "resolve: Hacking service resolution for '" + instanceName + "' type '"+serviceType+"'"); - chipMdnsCallback.handleServiceResolve( - instanceName, - serviceType, - "10.0.2.2", - 5540, - attributes, - callbackHandle, - contextHandle); - } - }; - this.nsdManager.resolveService( serviceInfo, new NsdManager.ResolveListener() { @@ -144,8 +119,6 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { } }); mainThreadHandler.postDelayed(timeoutRunnable, RESOLVE_SERVICE_TIMEOUT); - - mainThreadHandler.postDelayed(hack, RESOLVE_SERVICE_FOUND); } @Override From 99f0766ffbc529dfa32199545cbd36114b603c29 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Tue, 31 May 2022 19:49:30 -0700 Subject: [PATCH 04/12] remove hack --- .../android/java/chip/platform/NsdManagerServiceResolver.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index 387c93521be274..17391c648420b4 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -33,7 +33,6 @@ public class NsdManagerServiceResolver implements ServiceResolver { private static final String TAG = NsdManagerServiceResolver.class.getSimpleName(); private static final long RESOLVE_SERVICE_TIMEOUT = 30000; - private static final long RESOLVE_SERVICE_FOUND = 3000; private final NsdManager nsdManager; private MulticastLock multicastLock; private Handler mainThreadHandler; From 9b7e8abc9363316306781f360b34985c1532f4b7 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 1 Jun 2022 16:21:53 -0700 Subject: [PATCH 05/12] address feedback, formatting --- .../server/MatterCommissioningPrompter.java | 5 +-- examples/tv-casting-app/linux/args.gni | 2 + src/platform/android/DnssdImpl.cpp | 42 ++++++++++--------- src/platform/android/DnssdImpl.h | 1 - .../chip/platform/ChipMdnsCallbackImpl.java | 4 +- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java index fc284d8957d99f..2e9c36a3dafb81 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java @@ -112,10 +112,7 @@ public void promptCommissioningSucceeded(int vendorId, int productId, String com } public void promptCommissioningFailed(String commissioneeName, String error) { - Log.d( - TAG, - "Received prompt for failure Commissionee: " - + commissioneeName); + Log.d(TAG, "Received prompt for failure Commissionee: " + commissioneeName); NotificationCompat.Builder builder = new NotificationCompat.Builder(activity, CHANNEL_ID) .setSmallIcon(R.drawable.ic_baseline_clear_24) diff --git a/examples/tv-casting-app/linux/args.gni b/examples/tv-casting-app/linux/args.gni index 3175a832930e5e..ba9be5eb3c67a0 100644 --- a/examples/tv-casting-app/linux/args.gni +++ b/examples/tv-casting-app/linux/args.gni @@ -29,3 +29,5 @@ chip_build_libshell = true chip_enable_additional_data_advertising = true chip_enable_rotating_device_id = true + +chip_config_network_layer_ble = false diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index 806ae5ae215322..9db21f822b6adb 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -38,14 +38,14 @@ namespace Dnssd { using namespace chip::Platform; namespace { -jobject sResolverObject = nullptr; -jobject sMdnsCallbackObject = nullptr; -jmethodID sResolveMethod = nullptr; +jobject sResolverObject = nullptr; +jobject sMdnsCallbackObject = nullptr; +jmethodID sResolveMethod = nullptr; jmethodID sGetAttributeKeysMethod = nullptr; jmethodID sGetAttributeDataMethod = nullptr; jclass sMdnsCallbackClass = nullptr; -jmethodID sPublishMethod = nullptr; -jmethodID sRemoveServicesMethod = nullptr; +jmethodID sPublishMethod = nullptr; +jmethodID sRemoveServicesMethod = nullptr; } // namespace // Implementation of functions declared in lib/dnssd/platform/Dnssd.h @@ -234,6 +234,24 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) } } +/** + * Helper function which returns the jstring key as a null-terminated char string for the purpose + * of constructing the TextEntry list + */ +const char * getTxtInfoKey(JNIEnv * env, jstring key) +{ + const char * keyList[] = { "D", "VP", "AP", "CM", "DT", "DN", "RI", "PI", "PH", "CRI", "CRA", "T" }; + JniUtfString jniKey(env, key); + for (auto & info : keyList) + { + if (strcmp(info, jniKey.c_str()) == 0) + { + return info; + } + } + return ""; +} + void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject attributes, jlong callbackHandle, jlong contextHandle) { @@ -325,19 +343,5 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j } } -const char * getTxtInfoKey(JNIEnv * env, jstring key) -{ - const char * keyList[] = { "D", "VP", "AP", "CM", "DT", "DN", "RI", "PI", "PH", "CRI", "CRA", "T" }; - JniUtfString jniKey(env, key); - for (auto & info : keyList) - { - if (strcmp(info, jniKey.c_str()) == 0) - { - return info; - } - } - return ""; -} - } // namespace Dnssd } // namespace chip diff --git a/src/platform/android/DnssdImpl.h b/src/platform/android/DnssdImpl.h index 7b40976e91f211..f43de4578d5c02 100644 --- a/src/platform/android/DnssdImpl.h +++ b/src/platform/android/DnssdImpl.h @@ -35,6 +35,5 @@ void InitializeWithObjects(jobject resolverObject, jobject chipMdnsCallbackObjec void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject attributes, jlong callbackHandle, jlong contextHandle); -const char * getTxtInfoKey(JNIEnv * env, jstring key); } // namespace Dnssd } // namespace chip diff --git a/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java b/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java index c20d0d496b019a..40f9486ecc8275 100644 --- a/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java +++ b/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java @@ -32,8 +32,8 @@ public native void handleServiceResolve( public String[] getAttributeKeys(Map attributes) { return attributes.keySet().toArray(new String[attributes.size()]); } - + public byte[] getAttributeData(Map attributes, String key) { return attributes.get(key); - } + } } From 00046d0924efca28045f478664a06cdbbfa96142 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Thu, 2 Jun 2022 04:57:20 -0700 Subject: [PATCH 06/12] fix darwin build --- examples/tv-casting-app/linux/args.gni | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/tv-casting-app/linux/args.gni b/examples/tv-casting-app/linux/args.gni index ba9be5eb3c67a0..3175a832930e5e 100644 --- a/examples/tv-casting-app/linux/args.gni +++ b/examples/tv-casting-app/linux/args.gni @@ -29,5 +29,3 @@ chip_build_libshell = true chip_enable_additional_data_advertising = true chip_enable_rotating_device_id = true - -chip_config_network_layer_ble = false From 393f2d2215eaec7a90abb11ca35df988aca0ae14 Mon Sep 17 00:00:00 2001 From: "restyled-io[bot]" <32688539+restyled-io[bot]@users.noreply.github.com> Date: Thu, 2 Jun 2022 05:18:34 -0700 Subject: [PATCH 07/12] Restyle Add text entries to mDNS service discovery response (#19028) * Restyled by whitespace * Restyled by google-java-format Co-authored-by: Restyled.io --- .../chip/platform/NsdManagerServiceResolver.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java index 17391c648420b4..780d54662bcfca 100644 --- a/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java +++ b/src/platform/android/java/chip/platform/NsdManagerServiceResolver.java @@ -26,9 +26,7 @@ import android.os.Looper; import android.util.Log; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class NsdManagerServiceResolver implements ServiceResolver { private static final String TAG = NsdManagerServiceResolver.class.getSimpleName(); @@ -60,7 +58,13 @@ public void resolve( NsdServiceInfo serviceInfo = new NsdServiceInfo(); serviceInfo.setServiceName(instanceName); serviceInfo.setServiceType(serviceType); - Log.d(TAG, "resolve: Starting service resolution for '" + instanceName + "' type '"+serviceType+"'"); + Log.d( + TAG, + "resolve: Starting service resolution for '" + + instanceName + + "' type '" + + serviceType + + "'"); Runnable timeoutRunnable = new Runnable() { @@ -94,7 +98,7 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { } @Override - public void onServiceResolved(NsdServiceInfo serviceInfo) { + public void onServiceResolved(NsdServiceInfo serviceInfo) { Log.i( TAG, "Resolved service '" From cf3633306593ccc77c88b27e94aeab15f4c5fece Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Thu, 2 Jun 2022 13:26:49 -0700 Subject: [PATCH 08/12] address comments --- src/platform/android/DnssdImpl.cpp | 68 +++++++++++-------- src/platform/android/DnssdImpl.h | 2 +- .../java/chip/platform/ChipMdnsCallback.java | 2 +- .../chip/platform/ChipMdnsCallbackImpl.java | 10 +-- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index 9db21f822b6adb..49735ce4f2f869 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -41,8 +41,8 @@ namespace { jobject sResolverObject = nullptr; jobject sMdnsCallbackObject = nullptr; jmethodID sResolveMethod = nullptr; -jmethodID sGetAttributeKeysMethod = nullptr; -jmethodID sGetAttributeDataMethod = nullptr; +jmethodID sGetTextEntryKeysMethod = nullptr; +jmethodID sGetTextEntryDataMethod = nullptr; jclass sMdnsCallbackClass = nullptr; jmethodID sPublishMethod = nullptr; jmethodID sRemoveServicesMethod = nullptr; @@ -193,9 +193,9 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) VerifyOrReturn(resolverClass != nullptr, ChipLogError(Discovery, "Failed to get Resolver Java class")); - sGetAttributeKeysMethod = env->GetMethodID(sMdnsCallbackClass, "getAttributeKeys", "(Ljava/util/Map;)[Ljava/lang/String;"); + sGetTextEntryKeysMethod = env->GetMethodID(sMdnsCallbackClass, "getTextEntryKeys", "(Ljava/util/Map;)[Ljava/lang/String;"); - sGetAttributeDataMethod = env->GetMethodID(sMdnsCallbackClass, "getAttributeData", "(Ljava/util/Map;Ljava/lang/String;)[B"); + sGetTextEntryDataMethod = env->GetMethodID(sMdnsCallbackClass, "getTextEntryData", "(Ljava/util/Map;Ljava/lang/String;)[B"); sResolveMethod = env->GetMethodID(resolverClass, "resolve", "(Ljava/lang/String;Ljava/lang/String;JJLchip/platform/ChipMdnsCallback;)V"); @@ -205,15 +205,15 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) env->ExceptionClear(); } - if (sGetAttributeKeysMethod == nullptr) + if (sGetTextEntryKeysMethod == nullptr) { - ChipLogError(Discovery, "Failed to access MdnsCallback 'getAttributeKeys' method"); + ChipLogError(Discovery, "Failed to access MdnsCallback 'getTextEntryKeys' method"); env->ExceptionClear(); } - if (sGetAttributeDataMethod == nullptr) + if (sGetTextEntryDataMethod == nullptr) { - ChipLogError(Discovery, "Failed to access MdnsCallback 'getAttributeData' method"); + ChipLogError(Discovery, "Failed to access MdnsCallback 'getTextEntryData' method"); env->ExceptionClear(); } @@ -235,8 +235,10 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) } /** - * Helper function which returns the jstring key as a null-terminated char string for the purpose - * of constructing the TextEntry list + * Returns a static `const char *` string that is equivalent to the passed in jstring key + * so that the jstring can be released while the key value remains valid. + * + * Only supports known Matter DNSSD TXT key values, returns empty string otherwise. */ const char * getTxtInfoKey(JNIEnv * env, jstring key) { @@ -252,7 +254,7 @@ const char * getTxtInfoKey(JNIEnv * env, jstring key) return ""; } -void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject attributes, jlong callbackHandle, +void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject textEntries, jlong callbackHandle, jlong contextHandle) { VerifyOrReturn(callbackHandle != 0, ChipLogError(Discovery, "HandleResolve called with callback equal to nullptr")); @@ -282,51 +284,63 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j CopyString(service.mName, jniInstanceName.c_str()); CopyString(service.mType, jniServiceType.c_str()); service.mPort = static_cast(port); + service.mTextEntrySize = 0; + service.mTextEntries = nullptr; - if (attributes != nullptr) + // Note on alloc/free memory use + // We are only allocating the entries list and the data field of each entry + // so we free these in the exit section + if (textEntries != nullptr) { - jobjectArray keys = (jobjectArray) env->CallObjectMethod(sMdnsCallbackObject, sGetAttributeKeysMethod, attributes); + jobjectArray keys = (jobjectArray) env->CallObjectMethod(sMdnsCallbackObject, sGetTextEntryKeysMethod, textEntries); size_t size = env->GetArrayLength(keys); - TextEntry * entries = new TextEntry[size]; + TextEntry * entries = new (std::nothrow) TextEntry[size]; + if (entries == nullptr) + { + ChipLogError(Discovery, "entries alloc failure"); + goto exit; + } + service.mTextEntries = entries; for (size_t i = 0; i < size; i++) { jstring jniKeyObject = (jstring) env->GetObjectArrayElement(keys, i); entries[i].mKey = getTxtInfoKey(env, jniKeyObject); jbyteArray datas = - (jbyteArray) env->CallObjectMethod(sMdnsCallbackObject, sGetAttributeDataMethod, attributes, jniKeyObject); + (jbyteArray) env->CallObjectMethod(sMdnsCallbackObject, sGetTextEntryDataMethod, textEntries, jniKeyObject); if (datas != nullptr) { size_t dataSize = env->GetArrayLength(datas); - uint8_t * data = new uint8_t[dataSize + 1]; + uint8_t * data = new (std::nothrow) uint8_t[dataSize]; + if (data == nullptr) + { + ChipLogError(Discovery, "data alloc failure"); + goto exit; + } + jbyte * jnidata = env->GetByteArrayElements(datas, nullptr); for (size_t j = 0; j < dataSize; j++) { - data[j] = (uint8_t) jnidata[j]; + data[j] = static_cast(jnidata[j]); } entries[i].mDataSize = dataSize; entries[i].mData = data; + ChipLogProgress(Discovery, " ----- entry [%u] : %s %s\n", static_cast(i), entries[i].mKey, - (char *) (entries[i].mData)); + std::string(reinterpret_cast(data), dataSize).c_str()); } else { - ChipLogProgress(Discovery, " ----- key=%s", entries[i].mKey); + ChipLogProgress(Discovery, " ----- entry [%u] : %s NULL\n", static_cast(i), entries[i].mKey); entries[i].mDataSize = 0; entries[i].mData = nullptr; } + service.mTextEntrySize = size; } - service.mTextEntrySize = size; - service.mTextEntries = entries; - } - else - { - ChipLogError(Discovery, "attributes is null"); - service.mTextEntrySize = 0; - service.mTextEntries = nullptr; } +exit: dispatch(CHIP_NO_ERROR, &service, &ipAddress); if (service.mTextEntries != nullptr) diff --git a/src/platform/android/DnssdImpl.h b/src/platform/android/DnssdImpl.h index f43de4578d5c02..688f5cb2a597db 100644 --- a/src/platform/android/DnssdImpl.h +++ b/src/platform/android/DnssdImpl.h @@ -32,7 +32,7 @@ void InitializeWithObjects(jobject resolverObject, jobject chipMdnsCallbackObjec /** * Pass results of the service resolution to the CHIP stack. */ -void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject attributes, jlong callbackHandle, +void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject textEntries, jlong callbackHandle, jlong contextHandle); } // namespace Dnssd diff --git a/src/platform/android/java/chip/platform/ChipMdnsCallback.java b/src/platform/android/java/chip/platform/ChipMdnsCallback.java index 3249c18cedb59f..bbb6701ec8f633 100644 --- a/src/platform/android/java/chip/platform/ChipMdnsCallback.java +++ b/src/platform/android/java/chip/platform/ChipMdnsCallback.java @@ -26,7 +26,7 @@ void handleServiceResolve( String serviceType, String address, int port, - Map attributes, + Map textEntries, long callbackHandle, long contextHandle); } diff --git a/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java b/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java index 40f9486ecc8275..60922641ab55f9 100644 --- a/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java +++ b/src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java @@ -25,15 +25,15 @@ public native void handleServiceResolve( String serviceType, String address, int port, - Map attributes, + Map textEntries, long callbackHandle, long contextHandle); - public String[] getAttributeKeys(Map attributes) { - return attributes.keySet().toArray(new String[attributes.size()]); + public String[] getTextEntryKeys(Map textEntries) { + return textEntries.keySet().toArray(new String[textEntries.size()]); } - public byte[] getAttributeData(Map attributes, String key) { - return attributes.get(key); + public byte[] getTextEntryData(Map textEntries, String key) { + return textEntries.get(key); } } From 029d077203112de2568afa5d759e60aa2b2fe9a3 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Thu, 2 Jun 2022 13:50:35 -0700 Subject: [PATCH 09/12] address comments --- src/platform/android/DnssdImpl.cpp | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index 49735ce4f2f869..ca2af021e39929 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -234,26 +234,6 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject) } } -/** - * Returns a static `const char *` string that is equivalent to the passed in jstring key - * so that the jstring can be released while the key value remains valid. - * - * Only supports known Matter DNSSD TXT key values, returns empty string otherwise. - */ -const char * getTxtInfoKey(JNIEnv * env, jstring key) -{ - const char * keyList[] = { "D", "VP", "AP", "CM", "DT", "DN", "RI", "PI", "PH", "CRI", "CRA", "T" }; - JniUtfString jniKey(env, key); - for (auto & info : keyList) - { - if (strcmp(info, jniKey.c_str()) == 0) - { - return info; - } - } - return ""; -} - void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject textEntries, jlong callbackHandle, jlong contextHandle) { @@ -304,7 +284,8 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j for (size_t i = 0; i < size; i++) { jstring jniKeyObject = (jstring) env->GetObjectArrayElement(keys, i); - entries[i].mKey = getTxtInfoKey(env, jniKeyObject); + JniUtfString key(env, jniKeyObject); + entries[i].mKey = strdup(key.c_str()); jbyteArray datas = (jbyteArray) env->CallObjectMethod(sMdnsCallbackObject, sGetTextEntryDataMethod, textEntries, jniKeyObject); @@ -348,6 +329,7 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j size_t size = service.mTextEntrySize; for (size_t i = 0; i < size; i++) { + delete[] service.mTextEntries[i].mKey; if (service.mTextEntries[i].mData != nullptr) { delete[] service.mTextEntries[i].mData; From 1cda304b23182663a7dc876e9a07e89ef3516b5e Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Thu, 2 Jun 2022 18:56:00 -0700 Subject: [PATCH 10/12] address comments --- src/platform/android/DnssdImpl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index ca2af021e39929..bf9a091ca9411f 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -280,6 +280,7 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j ChipLogError(Discovery, "entries alloc failure"); goto exit; } + memset(entries, 0, sizeof(entries[0]) * size); service.mTextEntries = entries; for (size_t i = 0; i < size; i++) { From 4e83a4d2bfec4acc68d90f8ddcc10ff8a270098c Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Thu, 2 Jun 2022 18:59:47 -0700 Subject: [PATCH 11/12] address comments --- src/platform/android/DnssdImpl.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index bf9a091ca9411f..3629f3513f4553 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -275,12 +275,9 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j jobjectArray keys = (jobjectArray) env->CallObjectMethod(sMdnsCallbackObject, sGetTextEntryKeysMethod, textEntries); size_t size = env->GetArrayLength(keys); TextEntry * entries = new (std::nothrow) TextEntry[size]; - if (entries == nullptr) - { - ChipLogError(Discovery, "entries alloc failure"); - goto exit; - } + VerifyOrExit(entries != nullptr, ChipLogError(Discovery, "entries alloc failure")); memset(entries, 0, sizeof(entries[0]) * size); + service.mTextEntries = entries; for (size_t i = 0; i < size; i++) { @@ -294,11 +291,7 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j { size_t dataSize = env->GetArrayLength(datas); uint8_t * data = new (std::nothrow) uint8_t[dataSize]; - if (data == nullptr) - { - ChipLogError(Discovery, "data alloc failure"); - goto exit; - } + VerifyOrExit(data != nullptr, ChipLogError(Discovery, "data alloc failure")); jbyte * jnidata = env->GetByteArrayElements(datas, nullptr); for (size_t j = 0; j < dataSize; j++) From a5e1de636fb0e84db8b2a0a6a5f826ecead745a5 Mon Sep 17 00:00:00 2001 From: Lazar Kovacic Date: Fri, 3 Jun 2022 10:36:19 +0200 Subject: [PATCH 12/12] Restyle merge --- src/platform/android/DnssdImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index 3629f3513f4553..a5b6fae94759ed 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -263,7 +263,7 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j DnssdService service = {}; CopyString(service.mName, jniInstanceName.c_str()); CopyString(service.mType, jniServiceType.c_str()); - service.mPort = static_cast(port); + service.mPort = static_cast(port); service.mTextEntrySize = 0; service.mTextEntries = nullptr;