Skip to content

Commit

Permalink
Added TXT record describing CRMP intervals to operational advertising.
Browse files Browse the repository at this point in the history
CRMP allows setting some intervals, which assumes that data
transmission does not take place in zero time and prevents
from unnecessary retransmissions. In particular sleepy end devices
may need more time on answering and controller should be aware
of that.

* Modified configs for RMP intervals defining their default
values, according to spec.
* Added TXT record containing default CRMP intervals information to
operational advertising message.
* For Thread sleepy end devices added additional time extension
by its sleeping period (in fact poll period).
* Fixed bug with passing local variable to otSrpSetHostName method
instead of static one.
  • Loading branch information
kkasperczyk-no committed Apr 7, 2021
1 parent bc3d6bf commit 60a2557
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 30 deletions.
15 changes: 9 additions & 6 deletions src/app/server/Mdns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <core/Optional.h>
#include <mdns/Advertiser.h>
#include <messaging/ReliableMessageProtocolConfig.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/ConfigurationManager.h>
#include <support/Span.h>
Expand Down Expand Up @@ -101,12 +102,14 @@ CHIP_ERROR AdvertiseOperational()

uint8_t mac[8];

const auto advertiseParameters = chip::Mdns::OperationalAdvertisingParameters()
.SetFabricId(fabricId)
.SetNodeId(GetCurrentNodeId())
.SetMac(FillMAC(mac))
.SetPort(CHIP_PORT)
.EnableIpV4(true);
const auto advertiseParameters =
chip::Mdns::OperationalAdvertisingParameters()
.SetFabricId(fabricId)
.SetNodeId(GetCurrentNodeId())
.SetMac(FillMAC(mac))
.SetCRMPRetryIntervals(CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL, CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL)
.SetPort(CHIP_PORT)
.EnableIpV4(true);

auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance();

Expand Down
6 changes: 6 additions & 0 deletions src/include/platform/ThreadStackManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class ThreadStackManager
CHIP_ERROR GetPrimary802154MACAddress(uint8_t * buf);
CHIP_ERROR GetFactoryAssignedEUI64(uint8_t (&buf)[8]);
CHIP_ERROR GetExternalIPv6Address(chip::Inet::IPAddress & addr);
CHIP_ERROR GetPollPeriod(uint32_t & buf);

CHIP_ERROR JoinerStart();
CHIP_ERROR SetThreadProvision(const Internal::DeviceNetworkInfo & netInfo);
Expand Down Expand Up @@ -347,6 +348,11 @@ inline CHIP_ERROR ThreadStackManager::GetExternalIPv6Address(chip::Inet::IPAddre
return static_cast<ImplClass *>(this)->_GetExternalIPv6Address(addr);
}

inline CHIP_ERROR ThreadStackManager::GetPollPeriod(uint32_t & buf)
{
return static_cast<ImplClass *>(this)->_GetPollPeriod(buf);
}

inline CHIP_ERROR ThreadStackManager::JoinerStart()
{
return static_cast<ImplClass *>(this)->_JoinerStart();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class GenericConfigurationManagerImpl
CHIP_ERROR _StorePrimaryWiFiMACAddress(const uint8_t * buf);
CHIP_ERROR _GetPrimary802154MACAddress(uint8_t * buf);
CHIP_ERROR _GetFactoryAssignedEUI64(uint8_t (&buf)[8]);
CHIP_ERROR _GetPollPeriod(uint32_t & buf);
CHIP_ERROR _StorePrimary802154MACAddress(const uint8_t * buf);
CHIP_ERROR _GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & dayOfMonth);
CHIP_ERROR _StoreManufacturingDate(const char * mfgDate, size_t mfgDateLen);
Expand Down
18 changes: 16 additions & 2 deletions src/lib/mdns/Advertiser.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,23 @@ class OperationalAdvertisingParameters : public BaseAdvertisingParams<Operationa
}
uint64_t GetNodeId() const { return mNodeId; }

OperationalAdvertisingParameters & SetCRMPRetryIntervals(uint32_t intervalIdle, uint32_t intervalActive)
{
mCrmpRetryIntervalIdle = intervalIdle;
mCrmpRetryIntervalActive = intervalActive;
return *this;
}
void GetCRMPRetryIntervals(uint32_t & intervalIdle, uint32_t & intervalActive) const
{
intervalIdle = mCrmpRetryIntervalIdle;
intervalActive = mCrmpRetryIntervalActive;
}

private:
uint64_t mFabricId = 0;
uint64_t mNodeId = 0;
uint64_t mFabricId = 0;
uint64_t mNodeId = 0;
uint32_t mCrmpRetryIntervalIdle = 0;
uint32_t mCrmpRetryIntervalActive = 0;
};

class CommissionAdvertisingParameters : public BaseAdvertisingParams<CommissionAdvertisingParameters>
Expand Down
68 changes: 62 additions & 6 deletions src/lib/mdns/Discovery_ImplPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,17 +263,73 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const OperationalAdvertisingParamete
mOperationalAdvertisingParams = params;
// TODO: There may be multilple device/fabrid ids after multi-admin.

ReturnErrorOnFailure(SetupHostname(params.GetMac()));
// According to spec CRI and CRA intervals should not exceed 1 hour (3600000 ms).
// TODO: That value should be defined in the ReliableMessageProtocolConfig.h,
// but for now it is not possible to access it from src/lib/mdns. It should be
// refactored after creating common DNS-SD layer.
constexpr uint32_t kMaxCRMPRetryInterval = 3600000;
// kMaxCRMPRetryInterval max value is 3600000, what gives 7 characters and newline
// necessary to represent it in the text form.
constexpr uint8_t kMaxCRMPRetryBufferSize = 7 + 1;
char crmpRetryIntervalIdleBuf[kMaxCRMPRetryBufferSize];
char crmpRetryIntervalActiveBuf[kMaxCRMPRetryBufferSize];
TextEntry crmpRetryIntervalEntries[2];
size_t textEntrySize = 0;
uint32_t crmpRetryIntervalIdle, crmpRetryIntervalActive;
int writtenCharactersNumber;
params.GetCRMPRetryIntervals(crmpRetryIntervalIdle, crmpRetryIntervalActive);

// TODO: Issue #5833 - CRMP retry intervals should be updated on the poll period value
// change or device type change.
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
if (chip::DeviceLayer::ConnectivityMgr().GetThreadDeviceType() ==
chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_SleepyEndDevice)
{
uint32_t sedPollPeriod;
ReturnErrorOnFailure(chip::DeviceLayer::ThreadStackMgr().GetPollPeriod(sedPollPeriod));
// Increment default CRMP retry intervals by SED poll period to be on the safe side
// and avoid unnecessary retransmissions.
crmpRetryIntervalIdle += sedPollPeriod;
crmpRetryIntervalActive += sedPollPeriod;
}
#endif

if (crmpRetryIntervalIdle > kMaxCRMPRetryInterval)
{
ChipLogProgress(Discovery, "CRMP retry interval idle value exceeds allowed range of 1 hour, using maximum available",
chip::ErrorStr(error));
crmpRetryIntervalIdle = kMaxCRMPRetryInterval;
}
writtenCharactersNumber = snprintf(crmpRetryIntervalIdleBuf, sizeof(crmpRetryIntervalIdleBuf), "%u", crmpRetryIntervalIdle);
VerifyOrReturnError((writtenCharactersNumber > 0) && (writtenCharactersNumber < kMaxCRMPRetryBufferSize),
CHIP_ERROR_INVALID_STRING_LENGTH);
crmpRetryIntervalEntries[textEntrySize++] = { "CRI", reinterpret_cast<const uint8_t *>(crmpRetryIntervalIdleBuf),
strlen(crmpRetryIntervalIdleBuf) };

if (crmpRetryIntervalActive > kMaxCRMPRetryInterval)
{
ChipLogProgress(Discovery, "CRMP retry interval active value exceeds allowed range of 1 hour, using maximum available",
chip::ErrorStr(error));
crmpRetryIntervalActive = kMaxCRMPRetryInterval;
}
writtenCharactersNumber =
snprintf(crmpRetryIntervalActiveBuf, sizeof(crmpRetryIntervalActiveBuf), "%u", crmpRetryIntervalActive);
VerifyOrReturnError((writtenCharactersNumber > 0) && (writtenCharactersNumber < kMaxCRMPRetryBufferSize),
CHIP_ERROR_INVALID_STRING_LENGTH);
crmpRetryIntervalEntries[textEntrySize++] = { "CRA", reinterpret_cast<const uint8_t *>(crmpRetryIntervalActiveBuf),
strlen(crmpRetryIntervalActiveBuf) };

ReturnErrorOnFailure(SetupHostname(params.GetMac()));
ReturnErrorOnFailure(MakeInstanceName(service.mName, sizeof(service.mName), params.GetFabricId(), params.GetNodeId()));
strncpy(service.mType, "_chip", sizeof(service.mType));
service.mProtocol = MdnsServiceProtocol::kMdnsProtocolTcp;
service.mPort = CHIP_PORT;
service.mTextEntries = nullptr;
service.mTextEntrySize = 0;
service.mInterface = INET_NULL_INTERFACEID;
service.mAddressType = Inet::kIPAddressType_Any;
error = ChipMdnsPublishService(&service);
service.mTextEntries = crmpRetryIntervalEntries;
service.mTextEntrySize = textEntrySize;

service.mInterface = INET_NULL_INTERFACEID;
service.mAddressType = Inet::kIPAddressType_Any;
error = ChipMdnsPublishService(&service);

return error;
}
Expand Down
32 changes: 19 additions & 13 deletions src/messaging/ReliableMessageProtocolConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,33 @@ namespace Messaging {
#endif // CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT

/**
* @def CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRANS_TIMEOUT_TICK
* @def CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL
*
* @brief
* The default retransmission timeout in milliseconds.
* Active retransmit interval, or time to wait before retransmission after
* subsequent failures in milliseconds.
*
* This is the default value, that might be adjusted by end device depending on its
* needs (e.g. sleeping period) using Service Discovery TXT record CRA key.
*
*/
#ifndef CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRANS_TIMEOUT_TICK
#define CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRANS_TIMEOUT_TICK (8)
#endif // CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRANS_TIMEOUT_TICK
#ifndef CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL
#define CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL (300)
#endif // CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL

/**
* @def CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRANS_TIMEOUT_TICK
* @def CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
*
* @brief
* The default long retransmission timeout in milliseconds
* to include sleepy destinaton nodes.
* Initial retransmission interval, or time to wait before retransmission after first
* failure in milliseconds.
*
* This is the default value, that might be adjusted by end device depending on its
* needs (e.g. sleeping period) using Service Discovery TXT record CRI key.
*/
#ifndef CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRANS_TIMEOUT_TICK
#define CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRANS_TIMEOUT_TICK (8)
#endif // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRANS_TIMEOUT_TICK
#ifndef CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
#define CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL (5000)
#endif // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL

/**
* @def CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT_TICK
Expand Down Expand Up @@ -116,8 +122,8 @@ struct ReliableMessageProtocolConfig
uint8_t mMaxRetrans; /**< Configurable max value for retransmissions in the ExchangeContext. */
};

const ReliableMessageProtocolConfig gDefaultReliableMessageProtocolConfig = { CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRANS_TIMEOUT_TICK,
CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRANS_TIMEOUT_TICK,
const ReliableMessageProtocolConfig gDefaultReliableMessageProtocolConfig = { CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL,
CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL,
CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT_TICK,
CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS };

Expand Down
4 changes: 2 additions & 2 deletions src/messaging/tests/TestReliableMessageProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ void CheckResendMessage(nlTestSuite * inSuite, void * inContext)
NL_TEST_ASSERT(inSuite, rc != nullptr);

rc->SetConfig({
1, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRANS_TIMEOUT_TICK
1, // CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRANS_TIMEOUT_TICK
1, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
1, // CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL
1, // CHIP_CONFIG_RMP_DEFAULT_ACK_TIMEOUT_TICK
3, // CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS
});
Expand Down
5 changes: 5 additions & 0 deletions src/platform/Linux/ThreadStackManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,11 @@ CHIP_ERROR ThreadStackManagerImpl::_GetExternalIPv6Address(chip::Inet::IPAddress
return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_GetPollPeriod(uint32_t & buf)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ThreadStackManagerImpl::_JoinerStart()
{
return CHIP_ERROR_NOT_IMPLEMENTED;
Expand Down
2 changes: 2 additions & 0 deletions src/platform/Linux/ThreadStackManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class ThreadStackManagerImpl : public ThreadStackManager

CHIP_ERROR _GetExternalIPv6Address(chip::Inet::IPAddress & addr);

CHIP_ERROR _GetPollPeriod(uint32_t & buf);

CHIP_ERROR _JoinerStart();

~ThreadStackManagerImpl() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,15 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetExternalIPv6
return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
}

template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetPollPeriod(uint32_t & buf)
{
Impl()->LockThreadStack();
buf = otLinkGetPollPeriod(mOTInst);
Impl()->UnlockThreadStack();
return CHIP_NO_ERROR;
};

template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::DoInit(otInstance * otInst)
{
Expand Down Expand Up @@ -1259,7 +1268,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_SetupSrpHost(co
if (strcmp(mSrpClient.mHostName, aHostName) != 0)
{
strcpy(mSrpClient.mHostName, aHostName);
error = MapOpenThreadError(otSrpClientSetHostName(mOTInst, aHostName));
error = MapOpenThreadError(otSrpClientSetHostName(mOTInst, mSrpClient.mHostName));
SuccessOrExit(error);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class GenericThreadStackManagerImpl_OpenThread
CHIP_ERROR _GetPrimary802154MACAddress(uint8_t * buf);
CHIP_ERROR _GetFactoryAssignedEUI64(uint8_t (&buf)[8]);
CHIP_ERROR _GetExternalIPv6Address(chip::Inet::IPAddress & addr);
CHIP_ERROR _GetPollPeriod(uint32_t & buf);
void _OnWoBLEAdvertisingStart(void);
void _OnWoBLEAdvertisingStop(void);

Expand Down

0 comments on commit 60a2557

Please sign in to comment.