Skip to content

Commit

Permalink
[Android] Support Android MDNS subtype (project-chip#25235)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeonghwan7 committed Apr 18, 2023
1 parent 8809801 commit a01ccf7
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 15 deletions.
4 changes: 1 addition & 3 deletions src/lib/dnssd/Discovery_ImplPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ static void HandleNodeIdResolve(void * context, DnssdService * result, const Spa
static void HandleNodeBrowse(void * context, DnssdService * services, size_t servicesSize, bool finalBrowse, CHIP_ERROR error)
{
ResolverDelegateProxy * proxy = static_cast<ResolverDelegateProxy *>(context);

if (error != CHIP_NO_ERROR)
{
// We don't have access to the ResolverProxy here to clear out its
Expand All @@ -166,8 +165,7 @@ static void HandleNodeBrowse(void * context, DnssdService * services, size_t ser
// TODO: Have a way to clear that state here.
proxy->Release();
return;
}

}
for (size_t i = 0; i < servicesSize; ++i)
{
proxy->Retain();
Expand Down
51 changes: 39 additions & 12 deletions src/platform/android/DnssdImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <jni.h>
#include <memory>
#include <string>
#include <sstream>

namespace chip {
namespace Dnssd {
Expand All @@ -52,6 +53,9 @@ jmethodID sRemoveServicesMethod = nullptr;

// Implementation of functions declared in lib/dnssd/platform/Dnssd.h

constexpr const char * kProtocolTcp = "._tcp";
constexpr const char * kProtocolUdp = "._udp";

CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context)
{
VerifyOrReturnError(initCallback != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
Expand Down Expand Up @@ -149,17 +153,41 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate()
return CHIP_NO_ERROR;
}

std::string GetFullType(const char * type, DnssdServiceProtocol protocol)
{
std::ostringstream typeBuilder;
typeBuilder << type;
typeBuilder << (protocol == DnssdServiceProtocol::kDnssdProtocolUdp ? kProtocolUdp : kProtocolTcp);
return typeBuilder.str();
}

std::string GetFullTypeWithSubTypes(const char * type, DnssdServiceProtocol protocol)
{
auto fullType = GetFullType(type, protocol);

std::string subtypeDelimiter = "._sub.";
size_t position = fullType.find(subtypeDelimiter);
if (position != std::string::npos)
{
fullType = fullType.substr(position + subtypeDelimiter.size()) + "," + fullType.substr(0, position);
}

return fullType;
}

std::string GetFullType(const DnssdService * service)
{
return GetFullType(service->mType, service->mProtocol);
}

CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType,
Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, intptr_t * browseIdentifier)
{
VerifyOrReturnError(type != nullptr && callback != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(sBrowserObject != nullptr && sBrowseMethod != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(sMdnsCallbackObject != nullptr, CHIP_ERROR_INCORRECT_STATE);

std::string serviceType = type;
serviceType += '.';
serviceType += (protocol == DnssdServiceProtocol::kDnssdProtocolUdp ? "_udp" : "_tcp");

std::string serviceType = GetFullTypeWithSubTypes(type, protocol);
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
UtfString jniServiceType(env, serviceType.c_str());

Expand Down Expand Up @@ -196,14 +224,18 @@ CHIP_ERROR extractProtocol(const char * serviceType, char (&outServiceName)[N],
outServiceName[lengthWithoutProtocol] = '\0'; // Set a null terminator

outProtocol = DnssdServiceProtocol::kDnssdProtocolUnknown;
if (strcmp("._tcp", dotPos) == 0)
if (strstr(dotPos,"._tcp") != 0)
{
outProtocol = DnssdServiceProtocol::kDnssdProtocolTcp;
}
else if (strcmp("._udp", dotPos) == 0)
else if (strstr(dotPos,"._udp") != 0)
{
outProtocol = DnssdServiceProtocol::kDnssdProtocolUdp;
}
else {
ChipLogError(Discovery,"Service type don't include neithor TCP nor UDP!");
return CHIP_ERROR_INVALID_ARGUMENT;
}

ReturnErrorCodeIf(outProtocol == DnssdServiceProtocol::kDnssdProtocolUnknown, CHIP_ERROR_INVALID_ARGUMENT);

Expand All @@ -216,10 +248,7 @@ CHIP_ERROR ChipDnssdResolve(DnssdService * service, Inet::InterfaceId interface,
VerifyOrReturnError(sResolverObject != nullptr && sResolveMethod != nullptr, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(sMdnsCallbackObject != nullptr, CHIP_ERROR_INCORRECT_STATE);

std::string serviceType = service->mType;
serviceType += '.';
serviceType += (service->mProtocol == DnssdServiceProtocol::kDnssdProtocolUdp ? "_udp" : "_tcp");

std::string serviceType = GetFullType(service);
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
UtfString jniInstanceName(env, service->mName);
UtfString jniServiceType(env, serviceType.c_str());
Expand Down Expand Up @@ -433,8 +462,6 @@ void HandleBrowse(jobjectArray instanceName, jstring serviceType, jlong callback
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
JniUtfString jniServiceType(env, serviceType);

VerifyOrReturn(strlen(jniServiceType.c_str()) <= kDnssdTypeAndProtocolMaxSize, dispatch(CHIP_ERROR_INVALID_ARGUMENT));

auto size = env->GetArrayLength(instanceName);
DnssdService * service = new DnssdService[size];
for (decltype(size) i = 0; i < size; i++)
Expand Down

0 comments on commit a01ccf7

Please sign in to comment.