Skip to content

Commit

Permalink
[mdns/srp] Implemented delayed mDNS platform initialization (#10222)
Browse files Browse the repository at this point in the history
The Mdns module doesn't wait for SRP platform to be initialized
and ready to operate before requesting adding/removing services.
SRP platform needs to remove on init all old services associated
with the host.

* Removed assigning mMdnsInitialized=true in
DiscoveryImplPlatform::Init() method, to be sure that
DiscoveryImplPlatform always waits for platform to be ready
and signal it by calling HandleMdnsInit callback
* Removed stopping services in DiscoveryImplPlatform::Start()
method, as it is already done one step earlier by StopPublishDevice()
method
* Added kMdnsPlatformInitialized CHIP event informing that mDNS
platform is initalized and posted event in HandleMdnsInit callback
* Added OnPlatformEvent in Mdns.cpp that handles
kMdnsPlatformInitialized and restarts advertising
* Added removing SRP host and services on SRP platform init
* Renamed FillMAC method to GetPrimaryMACAddress and moved it
to the ConfigurationMgr, as it is useful also for src/lib/mdns
and src/platform modules that should not use app/server API.
* Bump OpenThread repo version
* Bump OTBR-posix repo version
  • Loading branch information
kkasperczyk-no authored Oct 8, 2021
1 parent 9e96810 commit 14a04e9
Show file tree
Hide file tree
Showing 17 changed files with 218 additions and 31 deletions.
40 changes: 19 additions & 21 deletions src/app/server/Mdns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,18 @@ bool HaveOperationalCredentials()
return false;
}

// Requires an 8-byte mac to accommodate thread.
chip::ByteSpan FillMAC(uint8_t (&mac)[8])
void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * event)
{
memset(mac, 0, 8);
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
if (chip::DeviceLayer::ThreadStackMgr().GetPrimary802154MACAddress(mac) == CHIP_NO_ERROR)
if (event->Type == DeviceLayer::DeviceEventType::kMdnsPlatformInitialized)
{
ChipLogDetail(Discovery, "Using Thread extended MAC for hostname.");
return chip::ByteSpan(mac, 8);
app::MdnsServer::Instance().StartServer();
}
#endif
if (DeviceLayer::ConfigurationMgr().GetPrimaryWiFiMACAddress(mac) == CHIP_NO_ERROR)
{
ChipLogDetail(Discovery, "Using wifi MAC for hostname");
return chip::ByteSpan(mac, 6);
}
ChipLogError(Discovery, "Wifi mac not known. Using a default.");
uint8_t temp[6] = { 0xEE, 0xAA, 0xBA, 0xDA, 0xBA, 0xD0 };
memcpy(mac, temp, 6);
return chip::ByteSpan(mac, 6);
}

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

} // namespace
Expand Down Expand Up @@ -257,12 +249,14 @@ CHIP_ERROR MdnsServer::AdvertiseOperational()
{
if (fabricInfo.IsInitialized())
{
uint8_t mac[8];
uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
MutableByteSpan mac(macBuffer);
chip::DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac);

const auto advertiseParameters =
chip::Mdns::OperationalAdvertisingParameters()
.SetPeerId(fabricInfo.GetPeerId())
.SetMac(FillMAC(mac))
.SetMac(mac)
.SetPort(GetSecuredPort())
.SetMRPRetryIntervals(Optional<uint32_t>(CHIP_CONFIG_MRP_DEFAULT_INITIAL_RETRY_INTERVAL),
Optional<uint32_t>(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL))
Expand Down Expand Up @@ -294,8 +288,10 @@ CHIP_ERROR MdnsServer::Advertise(bool commissionableNode, chip::Mdns::Commission

char pairingInst[chip::Mdns::kKeyPairingInstructionMaxLength + 1];

uint8_t mac[8];
advertiseParameters.SetMac(FillMAC(mac));
uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
MutableByteSpan mac(macBuffer);
chip::DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac);
advertiseParameters.SetMac(mac);

uint16_t value;
if (DeviceLayer::ConfigurationMgr().GetVendorId(value) != CHIP_NO_ERROR)
Expand Down Expand Up @@ -412,6 +408,8 @@ void MdnsServer::StartServer(chip::Mdns::CommissioningMode mode)

ClearTimeouts();

DeviceLayer::PlatformMgr().AddEventHandler(OnPlatformEventWrapper, 0);

CHIP_ERROR err = Mdns::ServiceAdvertiser::Instance().Init(&chip::DeviceLayer::InetLayer);
if (err != CHIP_NO_ERROR)
{
Expand Down
5 changes: 5 additions & 0 deletions src/include/platform/CHIPDeviceEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ enum PublicEventTypes
*
*/
kOperationalNetworkEnabled,

/**
* Signals that mDNS platform layer was initialized and is ready to operate.
*/
kMdnsPlatformInitialized,
};

/**
Expand Down
13 changes: 13 additions & 0 deletions src/include/platform/ConfigurationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <cstdint>

#include <lib/support/Span.h>
#include <platform/CHIPDeviceBuildConfig.h>
#include <platform/PersistedStorage.h>

Expand Down Expand Up @@ -60,6 +61,12 @@ class ConfigurationManager
kMaxPairingCodeLength = 16,
kMaxSerialNumberLength = 32,
kMaxFirmwareRevisionLength = 32,
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
kPrimaryMACAddressLength = 8,
#else
kPrimaryMACAddressLength = 6,
#endif
kMaxMACAddressLength = 8,
};

CHIP_ERROR GetVendorName(char * buf, size_t bufSize);
Expand All @@ -69,6 +76,7 @@ class ConfigurationManager
CHIP_ERROR GetProductRevisionString(char * buf, size_t bufSize);
CHIP_ERROR GetProductRevision(uint16_t & productRev);
CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize, size_t & serialNumLen);
CHIP_ERROR GetPrimaryMACAddress(MutableByteSpan buf);
CHIP_ERROR GetPrimaryWiFiMACAddress(uint8_t * buf);
CHIP_ERROR GetPrimary802154MACAddress(uint8_t * buf);
CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & dayOfMonth);
Expand Down Expand Up @@ -265,6 +273,11 @@ inline CHIP_ERROR ConfigurationManager::GetSerialNumber(char * buf, size_t bufSi
return static_cast<ImplClass *>(this)->_GetSerialNumber(buf, bufSize, serialNumLen);
}

inline CHIP_ERROR ConfigurationManager::GetPrimaryMACAddress(MutableByteSpan buf)
{
return static_cast<ImplClass *>(this)->_GetPrimaryMACAddress(buf);
}

inline CHIP_ERROR ConfigurationManager::GetPrimaryWiFiMACAddress(uint8_t * buf)
{
return static_cast<ImplClass *>(this)->_GetPrimaryWiFiMACAddress(buf);
Expand Down
5 changes: 5 additions & 0 deletions src/include/platform/PlatformManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@

namespace chip {

namespace Mdns {
class DiscoveryImplPlatform;
}

namespace DeviceLayer {

class PlatformManagerImpl;
Expand Down Expand Up @@ -176,6 +180,7 @@ class PlatformManager
friend class PlatformManagerImpl;
friend class ConnectivityManagerImpl;
friend class ConfigurationManagerImpl;
friend class Mdns::DiscoveryImplPlatform;
friend class TraitManager;
friend class ThreadStackManagerImpl;
friend class TimeSyncManager;
Expand Down
17 changes: 17 additions & 0 deletions src/include/platform/ThreadStackManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ using DnsResolveCallback = void (*)(void * context, chip::Mdns::MdnsService * re
using DnsBrowseCallback = void (*)(void * context, chip::Mdns::MdnsService * services, size_t servicesSize, CHIP_ERROR error);
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT

#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
using DnsAsyncReturnCallback = void (*)(void * context, CHIP_ERROR error);
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT

/**
* Provides features for initializing and interacting with the Thread stack on
* a chip-enabled device.
Expand Down Expand Up @@ -102,6 +106,8 @@ class ThreadStackManager
CHIP_ERROR InvalidateAllSrpServices(); ///< Mark all SRP services as invalid
CHIP_ERROR RemoveInvalidSrpServices(); ///< Remove SRP services marked as invalid
CHIP_ERROR SetupSrpHost(const char * aHostName);
CHIP_ERROR ClearSrpHost(const char * aHostName);
CHIP_ERROR SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback, DnsAsyncReturnCallback aErrorCallback, void * aContext);

#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
CHIP_ERROR DnsBrowse(const char * aServiceName, DnsBrowseCallback aCallback, void * aContext);
Expand Down Expand Up @@ -275,6 +281,17 @@ inline CHIP_ERROR ThreadStackManager::SetupSrpHost(const char * aHostName)
return static_cast<ImplClass *>(this)->_SetupSrpHost(aHostName);
}

inline CHIP_ERROR ThreadStackManager::ClearSrpHost(const char * aHostName)
{
return static_cast<ImplClass *>(this)->_ClearSrpHost(aHostName);
}

inline CHIP_ERROR ThreadStackManager::SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback,
DnsAsyncReturnCallback aErrorCallback, void * aContext)
{
return static_cast<ImplClass *>(this)->_SetSrpDnsCallbacks(aInitCallback, aErrorCallback, aContext);
}

#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
inline CHIP_ERROR ThreadStackManager::DnsBrowse(const char * aServiceName, DnsBrowseCallback aCallback, void * aContext)
{
Expand Down
28 changes: 28 additions & 0 deletions src/include/platform/internal/GenericConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,34 @@ CHIP_ERROR GenericConfigurationManagerImpl<ImplClass>::_StorePrimaryWiFiMACAddre
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}

template <class ImplClass>
CHIP_ERROR GenericConfigurationManagerImpl<ImplClass>::_GetPrimaryMACAddress(MutableByteSpan buf)
{
if (buf.size() != ConfigurationManager::kPrimaryMACAddressLength)
return CHIP_ERROR_INVALID_ARGUMENT;

memset(buf.data(), 0, buf.size());

#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
if (chip::DeviceLayer::ThreadStackMgr().GetPrimary802154MACAddress(buf.data()) == CHIP_NO_ERROR)
{
ChipLogDetail(DeviceLayer, "Using Thread extended MAC for hostname.");
return CHIP_NO_ERROR;
}
#else
if (DeviceLayer::ConfigurationMgr().GetPrimaryWiFiMACAddress(buf.data()) == CHIP_NO_ERROR)
{
ChipLogDetail(DeviceLayer, "Using wifi MAC for hostname");
return CHIP_NO_ERROR;
}
#endif

ChipLogError(DeviceLayer, "MAC is not known, using a default.");
uint8_t temp[ConfigurationManager::kMaxMACAddressLength] = { 0xEE, 0xAA, 0xBA, 0xDA, 0xBA, 0xD0, 0xDD, 0xCA };
memcpy(buf.data(), temp, buf.size());
return CHIP_NO_ERROR;
}

template <class ImplClass>
CHIP_ERROR GenericConfigurationManagerImpl<ImplClass>::_GetPrimary802154MACAddress(uint8_t * buf)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class GenericConfigurationManagerImpl
uint8_t & second);
CHIP_ERROR _GetSerialNumber(char * buf, size_t bufSize, size_t & serialNumLen);
CHIP_ERROR _StoreSerialNumber(const char * serialNum, size_t serialNumLen);
CHIP_ERROR _GetPrimaryMACAddress(MutableByteSpan buf);
CHIP_ERROR _GetPrimaryWiFiMACAddress(uint8_t * buf);
CHIP_ERROR _StorePrimaryWiFiMACAddress(const uint8_t * buf);
CHIP_ERROR _GetPrimary802154MACAddress(uint8_t * buf);
Expand Down
13 changes: 12 additions & 1 deletion src/lib/mdns/Discovery_ImplPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ CHIP_ERROR DiscoveryImplPlatform::InitImpl()
ReturnErrorCodeIf(mMdnsInitialized, CHIP_NO_ERROR);
ReturnErrorOnFailure(ChipMdnsInit(HandleMdnsInit, HandleMdnsError, this));
mCommissionInstanceName = GetRandU64();
mMdnsInitialized = true;

return CHIP_NO_ERROR;
}
Expand All @@ -66,6 +65,18 @@ void DiscoveryImplPlatform::HandleMdnsInit(void * context, CHIP_ERROR initError)
if (initError == CHIP_NO_ERROR)
{
publisher->mMdnsInitialized = true;

#if !CHIP_DEVICE_LAYER_NONE
// Post an event that will start advertising
chip::DeviceLayer::ChipDeviceEvent event;
event.Type = chip::DeviceLayer::DeviceEventType::kMdnsPlatformInitialized;

CHIP_ERROR error = chip::DeviceLayer::PlatformMgr().PostEvent(&event);
if (error != CHIP_NO_ERROR)
{
ChipLogError(Discovery, "Posting mDNS platform initialized event failed with %s", chip::ErrorStr(error));
}
#endif
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1506,7 +1506,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_JoinerStart(voi

#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT

static_assert(OPENTHREAD_API_VERSION >= 120, "SRP Client requires a more recent OpenThread version");
static_assert(OPENTHREAD_API_VERSION >= 156, "SRP Client requires a more recent OpenThread version");

template <class ImplClass>
void GenericThreadStackManagerImpl_OpenThread<ImplClass>::OnSrpClientNotification(otError aError,
Expand All @@ -1520,6 +1520,19 @@ void GenericThreadStackManagerImpl_OpenThread<ImplClass>::OnSrpClientNotificatio
case OT_ERROR_NONE: {
ChipLogProgress(DeviceLayer, "OnSrpClientNotification: Last requested operation completed successfully");

if (aHostInfo)
{
if (aHostInfo->mState == OT_SRP_CLIENT_ITEM_STATE_REMOVED)
{
// Clear memory for removed host
memset(ThreadStackMgrImpl().mSrpClient.mHostName, 0, sizeof(ThreadStackMgrImpl().mSrpClient.mHostName));

ThreadStackMgrImpl().mSrpClient.mIsInitialized = true;
ThreadStackMgrImpl().mSrpClient.mInitializedCallback(ThreadStackMgrImpl().mSrpClient.mCallbackContext,
CHIP_NO_ERROR);
}
}

if (aRemovedServices)
{
otSrpClientService * otService = const_cast<otSrpClientService *>(aRemovedServices);
Expand Down Expand Up @@ -1620,6 +1633,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_AddSrpService(c

Impl()->LockThreadStack();

VerifyOrExit(mSrpClient.mIsInitialized, error = CHIP_ERROR_WELL_UNINITIALIZED);
VerifyOrExit(aInstanceName, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(aName, error = CHIP_ERROR_INVALID_ARGUMENT);

Expand Down Expand Up @@ -1655,7 +1669,6 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_AddSrpService(c
srpService->mService.mName = alloc.Clone(aName);
srpService->mService.mPort = aPort;

#if OPENTHREAD_API_VERSION >= 132
VerifyOrExit(aSubTypes.size() < ArraySize(srpService->mSubTypes), error = CHIP_ERROR_BUFFER_TOO_SMALL);
entryId = 0;

Expand All @@ -1666,7 +1679,6 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_AddSrpService(c

srpService->mSubTypes[entryId] = nullptr;
srpService->mService.mSubTypeLabels = srpService->mSubTypes;
#endif

// Initialize TXT entries
VerifyOrExit(aTxtEntries.size() <= ArraySize(srpService->mTxtEntries), error = CHIP_ERROR_BUFFER_TOO_SMALL);
Expand Down Expand Up @@ -1712,6 +1724,8 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_RemoveSrpServic
CHIP_ERROR error = CHIP_NO_ERROR;
typename SrpClient::Service * srpService = nullptr;

VerifyOrExit(mSrpClient.mIsInitialized, error = CHIP_ERROR_WELL_UNINITIALIZED);

Impl()->LockThreadStack();

VerifyOrExit(aInstanceName, error = CHIP_ERROR_INVALID_ARGUMENT);
Expand Down Expand Up @@ -1760,6 +1774,8 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_RemoveInvalidSr
{
CHIP_ERROR error = CHIP_NO_ERROR;

VerifyOrExit(mSrpClient.mIsInitialized, error = CHIP_ERROR_WELL_UNINITIALIZED);

Impl()->LockThreadStack();

for (typename SrpClient::Service & service : mSrpClient.mServices)
Expand All @@ -1784,6 +1800,8 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetupSrpHost(co
CHIP_ERROR error = CHIP_NO_ERROR;
Inet::IPAddress hostAddress;

VerifyOrExit(mSrpClient.mIsInitialized, error = CHIP_ERROR_WELL_UNINITIALIZED);

Impl()->LockThreadStack();

VerifyOrExit(aHostName, error = CHIP_ERROR_INVALID_ARGUMENT);
Expand Down Expand Up @@ -1811,6 +1829,43 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetupSrpHost(co
return error;
}

template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_ClearSrpHost(const char * aHostName)
{
CHIP_ERROR error = CHIP_NO_ERROR;

Impl()->LockThreadStack();

VerifyOrExit(aHostName, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(strlen(aHostName) <= SrpClient::kMaxHostNameSize, error = CHIP_ERROR_INVALID_STRING_LENGTH);
VerifyOrExit(mSrpClient.mInitializedCallback, error = CHIP_ERROR_INCORRECT_STATE);

// Add host and remove it with notifying SRP server to clean old information related to the host.
// Avoid adding the same host name multiple times
if (strcmp(mSrpClient.mHostName, aHostName) != 0)
{
strcpy(mSrpClient.mHostName, aHostName);
error = MapOpenThreadError(otSrpClientSetHostName(mOTInst, mSrpClient.mHostName));
SuccessOrExit(error);
}
error = MapOpenThreadError(otSrpClientRemoveHostAndServices(mOTInst, false, true));

exit:
Impl()->UnlockThreadStack();

return error;
}

template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback,
DnsAsyncReturnCallback aErrorCallback,
void * aContext)
{
mSrpClient.mInitializedCallback = aInitCallback;
mSrpClient.mCallbackContext = aContext;
return CHIP_NO_ERROR;
}

#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::FromOtDnsResponseToMdnsData(
Expand Down
Loading

0 comments on commit 14a04e9

Please sign in to comment.