Skip to content

Commit

Permalink
[icd] Defer subscription resumption
Browse files Browse the repository at this point in the history
On some platforms, DNS-SD initialization is asynchronous and
any attempt to communicate with a peer node before that is
completed must fail.

Introduce kServerReady event that is emitted when all async
initialization tasks are completed (currently, only DNS-SD)
and resume persistent subscriptions in response to that
event.
  • Loading branch information
Damian-Nordic committed Jan 30, 2023
1 parent f5a8fd4 commit 4d51e00
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 4 deletions.
55 changes: 51 additions & 4 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#if CONFIG_NETWORK_LAYER_BLE
#include <ble/BLEEndPoint.h>
#endif
#include <dnssd/DnssdBuildConfig.h>
#include <inet/IPAddress.h>
#include <inet/InetError.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
Expand Down Expand Up @@ -353,12 +354,18 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams)
}
}

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
ResumeSubscriptions();
#endif

PlatformMgr().AddEventHandler(OnPlatformEventWrapper, 0);
PlatformMgr().HandleServerStarted();

#if CHIP_DNSSD_PLATFORM
// Platform DNS-SD implementation uses kPlatformDnssdInitialized event to signal that it's ready.
mIsDnssdReady = false;
#else
// Minimal mDNS implementation is initialized synchronously so mark it as ready.
mIsDnssdReady = true;
CheckServerReadyEvent();
#endif

exit:
if (err != CHIP_NO_ERROR)
{
Expand All @@ -372,6 +379,45 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams)
return err;
}

void Server::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event)
{
switch (event.Type)
{
case DeviceEventType::kServerReady:
#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
ResumeSubscriptions();
#endif
break;
#if CHIP_DNSSD_PLATFORM
case DeviceEventType::kDnssdPlatformInitialized:
if (!mIsDnssdReady)
{
mIsDnssdReady = true;
CheckServerReadyEvent();
}
break;
#endif
default:
break;
}
}

void Server::CheckServerReadyEvent()
{
// Check if all asynchronously initialized components (currently, only DNS-SD) are ready, and
// emit the 'server ready' event if so.
if (mIsDnssdReady)
{
ChipDeviceEvent event = { .Type = DeviceEventType::kServerReady };
PlatformMgr().PostEventOrDie(&event);
}
}

void Server::OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t)
{
Server::GetInstance().OnPlatformEvent(*event);
}

void Server::RejoinExistingMulticastGroups()
{
ChipLogProgress(AppServer, "Joining Multicast groups");
Expand Down Expand Up @@ -423,6 +469,7 @@ void Server::ScheduleFactoryReset()

void Server::Shutdown()
{
PlatformMgr().RemoveEventHandler(OnPlatformEventWrapper, 0);
mCASEServer.Shutdown();
mCASESessionManager.Shutdown();
app::DnssdServer::Instance().SetCommissioningModeProvider(nullptr);
Expand Down
5 changes: 5 additions & 0 deletions src/app/server/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ class Server
static Server sServer;

void InitFailSafe();
void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event);
void CheckServerReadyEvent();

static void OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t);

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
/**
Expand Down Expand Up @@ -561,6 +565,7 @@ class Server
uint16_t mOperationalServicePort;
uint16_t mUserDirectedCommissioningPort;
Inet::InterfaceId mInterfaceId;
bool mIsDnssdReady = false;
};

} // namespace chip
9 changes: 9 additions & 0 deletions src/include/platform/CHIPDeviceEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,15 @@ enum PublicEventTypes
* Signals that the state of the OTA engine changed.
*/
kOtaStateChanged,

/**
* Server initialization has completed.
*
* Signals that all server components have been initialized and the node is ready to establish
* connections with other nodes. This event can be used to trigger on-boot actions that require
* sending messages to other nodes.
*/
kServerReady,
};

/**
Expand Down
16 changes: 16 additions & 0 deletions src/lib/dnssd/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,30 @@

import("//build_overrides/chip.gni")
import("//build_overrides/nlunit_test.gni")

import("${chip_root}/build/chip/buildconfig_header.gni")
import("${chip_root}/src/platform/device.gni")

source_set("platform_header") {
sources = [ "platform/Dnssd.h" ]
}

buildconfig_header("dnssd_buildconfig") {
header = "DnssdBuildConfig.h"
header_dir = "dnssd"

chip_dnssd_minimal = chip_mdns == "minimal"
chip_dnssd_platform = chip_mdns == "platform"

defines = [
"CHIP_DNSSD_MINIMAL=${chip_dnssd_minimal}",
"CHIP_DNSSD_PLATFORM=${chip_dnssd_platform}",
]
}

static_library("dnssd") {
public_deps = [
":dnssd_buildconfig",
":platform_header",
"${chip_root}/src/crypto",
"${chip_root}/src/lib/core",
Expand Down

0 comments on commit 4d51e00

Please sign in to comment.