Skip to content

Commit

Permalink
Add text entries to mDNS service discovery response (#19027)
Browse files Browse the repository at this point in the history
* Add text entries to mDNS service discovery response

* fix android tv-app build

* remove hack

* remove hack

* address feedback, formatting

* fix darwin build

* Restyle Add text entries to mDNS service discovery response (#19028)

* Restyled by whitespace

* Restyled by google-java-format

Co-authored-by: Restyled.io <commits@restyled.io>

* address comments

* address comments

* address comments

* address comments

* Restyle merge

Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com>
Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: Lazar Kovacic <lkovacic@amazon.com>
  • Loading branch information
4 people authored and pull[bot] committed Aug 1, 2023
1 parent 9432f63 commit 4778163
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +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 vendor id:"
+ vendorId
+ " productId:"
+ productId
+ ". 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions src/platform/android/AndroidChipPlatform-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
101 changes: 94 additions & 7 deletions src/platform/android/DnssdImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <cstddef>
#include <jni.h>
#include <memory>
#include <string>

namespace chip {
Expand All @@ -37,11 +38,14 @@ namespace Dnssd {
using namespace chip::Platform;

namespace {
jobject sResolverObject = nullptr;
jobject sMdnsCallbackObject = nullptr;
jmethodID sResolveMethod = nullptr;
jmethodID sPublishMethod = nullptr;
jmethodID sRemoveServicesMethod = nullptr;
jobject sResolverObject = nullptr;
jobject sMdnsCallbackObject = nullptr;
jmethodID sResolveMethod = nullptr;
jmethodID sGetTextEntryKeysMethod = nullptr;
jmethodID sGetTextEntryDataMethod = nullptr;
jclass sMdnsCallbackClass = nullptr;
jmethodID sPublishMethod = nullptr;
jmethodID sRemoveServicesMethod = nullptr;
} // namespace

// Implementation of functions declared in lib/dnssd/platform/Dnssd.h
Expand Down Expand Up @@ -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"));

sGetTextEntryKeysMethod = env->GetMethodID(sMdnsCallbackClass, "getTextEntryKeys", "(Ljava/util/Map;)[Ljava/lang/String;");

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");
if (sResolveMethod == nullptr)
Expand All @@ -196,6 +205,18 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject)
env->ExceptionClear();
}

if (sGetTextEntryKeysMethod == nullptr)
{
ChipLogError(Discovery, "Failed to access MdnsCallback 'getTextEntryKeys' method");
env->ExceptionClear();
}

if (sGetTextEntryDataMethod == nullptr)
{
ChipLogError(Discovery, "Failed to access MdnsCallback 'getTextEntryData' 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");
Expand All @@ -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 textEntries, jlong callbackHandle,
jlong contextHandle)
{
VerifyOrReturn(callbackHandle != 0, ChipLogError(Discovery, "HandleResolve called with callback equal to nullptr"));

Expand Down Expand Up @@ -241,9 +263,74 @@ 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<uint16_t>(port);
service.mPort = static_cast<uint16_t>(port);
service.mTextEntrySize = 0;
service.mTextEntries = 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, sGetTextEntryKeysMethod, textEntries);
size_t size = env->GetArrayLength(keys);
TextEntry * entries = new (std::nothrow) TextEntry[size];
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++)
{
jstring jniKeyObject = (jstring) env->GetObjectArrayElement(keys, i);
JniUtfString key(env, jniKeyObject);
entries[i].mKey = strdup(key.c_str());

jbyteArray datas =
(jbyteArray) env->CallObjectMethod(sMdnsCallbackObject, sGetTextEntryDataMethod, textEntries, jniKeyObject);
if (datas != nullptr)
{
size_t dataSize = env->GetArrayLength(datas);
uint8_t * data = new (std::nothrow) uint8_t[dataSize];
VerifyOrExit(data != nullptr, ChipLogError(Discovery, "data alloc failure"));

jbyte * jnidata = env->GetByteArrayElements(datas, nullptr);
for (size_t j = 0; j < dataSize; j++)
{
data[j] = static_cast<uint8_t>(jnidata[j]);
}
entries[i].mDataSize = dataSize;
entries[i].mData = data;

ChipLogProgress(Discovery, " ----- entry [%u] : %s %s\n", static_cast<unsigned int>(i), entries[i].mKey,
std::string(reinterpret_cast<char *>(data), dataSize).c_str());
}
else
{
ChipLogProgress(Discovery, " ----- entry [%u] : %s NULL\n", static_cast<unsigned int>(i), entries[i].mKey);

entries[i].mDataSize = 0;
entries[i].mData = nullptr;
}
service.mTextEntrySize = size;
}
}

exit:
dispatch(CHIP_NO_ERROR, &service, &ipAddress);

if (service.mTextEntries != nullptr)
{
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;
}
}
delete[] service.mTextEntries;
}
}

} // namespace Dnssd
Expand Down
2 changes: 1 addition & 1 deletion src/platform/android/DnssdImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, jlong callbackHandle,
void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jobject textEntries, jlong callbackHandle,
jlong contextHandle);

} // namespace Dnssd
Expand Down
3 changes: 3 additions & 0 deletions src/platform/android/java/chip/platform/ChipMdnsCallback.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@
*/
package chip.platform;

import java.util.Map;

/** Interface for communicating with the CHIP mDNS stack. */
public interface ChipMdnsCallback {
void handleServiceResolve(
String instanceName,
String serviceType,
String address,
int port,
Map<String, byte[]> textEntries,
long callbackHandle,
long contextHandle);
}
11 changes: 11 additions & 0 deletions src/platform/android/java/chip/platform/ChipMdnsCallbackImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, byte[]> textEntries,
long callbackHandle,
long contextHandle);

public String[] getTextEntryKeys(Map<String, byte[]> textEntries) {
return textEntries.keySet().toArray(new String[textEntries.size()]);
}

public byte[] getTextEntryData(Map<String, byte[]> textEntries, String key) {
return textEntries.get(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ 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() {
Expand All @@ -67,6 +73,7 @@ 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();
}
Expand All @@ -82,7 +89,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();
Expand All @@ -104,6 +111,7 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) {
serviceType,
serviceInfo.getHost().getHostAddress(),
serviceInfo.getPort(),
serviceInfo.getAttributes(),
callbackHandle,
contextHandle);

Expand Down

0 comments on commit 4778163

Please sign in to comment.