Skip to content

Commit 1707934

Browse files
committed
[Tizen] Wait for mDNS on-browse events until timeout
Tizen Native API dos not deliver all-for-now event (such event is delivered by e.g. Avahi), so it is impossible to tell when the mDNS browsing shall be considered finished. This commit adds timeout event which is delivered after 250ms from the last on-browse event. This allows Tizen platform to discover more than one mDNS service on local network.
1 parent a58afc5 commit 1707934

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

src/platform/Tizen/DnssdImpl.cpp

+45-12
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ namespace {
4141

4242
constexpr uint8_t kDnssdKeyMaxSize = 32;
4343

44+
// The number of miliseconds which must elapse without a new "found" event before
45+
// mDNS browsing is considered finished. We need this timeout because Tizen Native
46+
// API does not deliver all-for-now signal (such signal is delivered by e.g. Avahi)
47+
// and the browsing callback is called multiple times (once for each service found).
48+
constexpr unsigned int kDnssdBrowseTimeoutMs = 250;
49+
4450
bool IsSupportedProtocol(DnssdServiceProtocol protocol)
4551
{
4652
return (protocol == DnssdServiceProtocol::kDnssdProtocolUdp) || (protocol == DnssdServiceProtocol::kDnssdProtocolTcp);
@@ -109,6 +115,22 @@ gboolean RegisterAsync(GMainLoop * mainLoop, gpointer userData)
109115
return true;
110116
}
111117

118+
gboolean OnBrowseTimeout(void * userData)
119+
{
120+
ChipLogDetail(DeviceLayer, "DNSsd %s: all for now", __func__);
121+
122+
auto * bCtx = reinterpret_cast<BrowseContext *>(userData);
123+
124+
bCtx->MainLoopQuit();
125+
bCtx->mCallback(bCtx->mCbContext, bCtx->mServices.data(), bCtx->mServices.size(), CHIP_NO_ERROR);
126+
127+
// After this point the context might be no longer valid
128+
bCtx->mInstance->RemoveContext(bCtx);
129+
130+
// This is a one-shot timer
131+
return FALSE;
132+
}
133+
112134
void OnBrowseAdd(BrowseContext * context, const char * type, const char * name, uint32_t interfaceId)
113135
{
114136
ChipLogDetail(DeviceLayer, "DNSsd %s: name: %s, type: %s, interfaceId: %u", __func__, name, type, interfaceId);
@@ -143,8 +165,20 @@ void OnBrowse(dnssd_service_state_e state, dnssd_service_h service, void * data)
143165
auto bCtx = reinterpret_cast<BrowseContext *>(data);
144166
int ret;
145167

146-
// Always stop browsing
147-
bCtx->MainLoopQuit();
168+
// If there is already a timeout source, so we need to cancel it.
169+
if (bCtx->mTimeoutSource != nullptr)
170+
{
171+
g_source_destroy(bCtx->mTimeoutSource);
172+
g_source_unref(bCtx->mTimeoutSource);
173+
}
174+
175+
// Start a timer, so we could detect when there is no more on-browse events.
176+
// The timeout callback function will be called in the same event loop as the
177+
// browse callback (this one), so locking is not required.
178+
auto * source = g_timeout_source_new(kDnssdBrowseTimeoutMs);
179+
g_source_set_callback(source, OnBrowseTimeout, bCtx, nullptr);
180+
g_source_attach(source, g_main_context_get_thread_default());
181+
bCtx->mTimeoutSource = source;
148182

149183
char * type = nullptr;
150184
char * name = nullptr;
@@ -173,23 +207,17 @@ void OnBrowse(dnssd_service_state_e state, dnssd_service_h service, void * data)
173207
OnBrowseRemove(bCtx, type, name, interfaceId);
174208
}
175209

176-
// For now, there is no way to wait for multiple services to be found.
177-
// Darwin implementation just checks if kDNSServiceFlagsMoreComing is set or not,
178-
// but it doesn't ensure that multiple services can be found.
179-
bCtx->mCallback(bCtx->mCbContext, bCtx->mServices.data(), bCtx->mServices.size(), CHIP_NO_ERROR);
180-
181210
exit:
182211

212+
dnssd_destroy_remote_service(service);
213+
183214
if (ret != DNSSD_ERROR_NONE)
184215
{
185216
bCtx->mCallback(bCtx->mCbContext, nullptr, 0, GetChipError(ret));
217+
// After this point the context might be no longer valid
218+
bCtx->mInstance->RemoveContext(bCtx);
186219
}
187220

188-
// After this point, the context might be no longer valid
189-
bCtx->mInstance->RemoveContext(bCtx);
190-
191-
dnssd_destroy_remote_service(service);
192-
193221
g_free(type);
194222
g_free(name);
195223
g_free(ifaceName);
@@ -412,6 +440,11 @@ BrowseContext::BrowseContext(DnssdTizen * instance, const char * type, DnssdServ
412440

413441
BrowseContext::~BrowseContext()
414442
{
443+
if (mTimeoutSource != nullptr)
444+
{
445+
g_source_destroy(mTimeoutSource);
446+
g_source_unref(mTimeoutSource);
447+
}
415448
if (mIsBrowsing)
416449
{
417450
dnssd_cancel_browse_service(mBrowserHandle);

src/platform/Tizen/DnssdImpl.h

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ struct BrowseContext : public GenericContext
8080
void * mCbContext;
8181

8282
dnssd_browser_h mBrowserHandle = 0;
83+
// The timeout source used to stop browsing
84+
GSource * mTimeoutSource = nullptr;
85+
8386
std::vector<DnssdService> mServices;
8487
bool mIsBrowsing = false;
8588

0 commit comments

Comments
 (0)