Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement User Directed Commissioning - Phase 1 #8034

Merged
merged 6 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions examples/minimal-mdns/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,22 +188,27 @@ int main(int argc, char ** args)
mdns::Minimal::Server<10 /* endpoints */> mdnsServer;
mdns::Minimal::QueryResponder<16 /* maxRecords */> queryResponder;

mdns::Minimal::QNamePart tcpServiceName[] = { kOperationalServiceName, kOperationalProtocol, kLocalDomain };
mdns::Minimal::QNamePart tcpServerServiceName[] = { gOptions.instanceName, kOperationalServiceName, kOperationalProtocol,
kLocalDomain };
mdns::Minimal::QNamePart udpServiceName[] = { kCommissionableServiceName, kCommissionProtocol, kLocalDomain };
mdns::Minimal::QNamePart udpServerServiceName[] = { gOptions.instanceName, kCommissionableServiceName, kCommissionProtocol,
kLocalDomain };
mdns::Minimal::QNamePart tcpServiceName[] = { chip::Mdns::kOperationalServiceName, chip::Mdns::kOperationalProtocol,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole file is using namespace chip, so I'd think you don't need the chip:: prefix on all of these...

chip::Mdns::kLocalDomain };
mdns::Minimal::QNamePart tcpServerServiceName[] = { gOptions.instanceName, chip::Mdns::kOperationalServiceName,
chip::Mdns::kOperationalProtocol, chip::Mdns::kLocalDomain };
mdns::Minimal::QNamePart udpServiceName[] = { chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol,
chip::Mdns::kLocalDomain };
mdns::Minimal::QNamePart udpServerServiceName[] = { gOptions.instanceName, chip::Mdns::kCommissionableServiceName,
chip::Mdns::kCommissionProtocol, chip::Mdns::kLocalDomain };

// several UDP versions for discriminators
mdns::Minimal::QNamePart udpDiscriminator1[] = { "S52", kSubtypeServiceNamePart, kCommissionableServiceName,
kCommissionProtocol, kLocalDomain };
mdns::Minimal::QNamePart udpDiscriminator2[] = { "V123", kSubtypeServiceNamePart, kCommissionableServiceName,
kCommissionProtocol, kLocalDomain };
mdns::Minimal::QNamePart udpDiscriminator3[] = { "L840", kSubtypeServiceNamePart, kCommissionableServiceName,
kCommissionProtocol, kLocalDomain };

mdns::Minimal::QNamePart serverName[] = { gOptions.instanceName, kLocalDomain };
mdns::Minimal::QNamePart udpDiscriminator1[] = { "S52", chip::Mdns::kSubtypeServiceNamePart,
chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol,
chip::Mdns::kLocalDomain };
mdns::Minimal::QNamePart udpDiscriminator2[] = { "V123", chip::Mdns::kSubtypeServiceNamePart,
chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol,
chip::Mdns::kLocalDomain };
mdns::Minimal::QNamePart udpDiscriminator3[] = { "L840", chip::Mdns::kSubtypeServiceNamePart,
chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol,
chip::Mdns::kLocalDomain };

mdns::Minimal::QNamePart serverName[] = { gOptions.instanceName, chip::Mdns::kLocalDomain };

mdns::Minimal::IPv4Responder ipv4Responder(serverName);
mdns::Minimal::IPv6Responder ipv6Responder(serverName);
Expand Down
7 changes: 7 additions & 0 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 <mdns/ServiceNaming.h>
#include <messaging/ReliableMessageProtocolConfig.h>
#if CONFIG_DEVICE_LAYER
#include <platform/CHIPDeviceLayer.h>
Expand Down Expand Up @@ -87,6 +88,12 @@ chip::ByteSpan FillMAC(uint8_t (&mac)[8])

} // namespace

CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen)
{
auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inside namespace Mdns {, so you shouldn't need all the prefixing.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its actually chip::app::Mdns so I don't think these can be removed

return mdnsAdvertiser.GetCommissionableInstanceName(buffer, bufferLen);
}

/// Set MDNS operational advertisement
CHIP_ERROR AdvertiseOperational()
{
Expand Down
3 changes: 3 additions & 0 deletions src/app/server/Mdns.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ void StartServer();

CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize);

/// Generates the (random) instance name that a CHIP device is to use for pre-commissioning DNS-SD
CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a followup, we should change this API to take a MutableSpan<char>...


} // namespace Mdns
} // namespace app
} // namespace chip
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ CHIP_ERROR pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissione

CHIP_ERROR pychip_DeviceController_DiscoverAllCommissionableNodes(chip::Controller::DeviceCommissioner * devCtrl)
{
Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kNone, 0);
Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kNone, (uint16_t) 0);
woody-apple marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kNone, (uint16_t) 0);
Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kNone, static_cast<uint16_t>(0));

return devCtrl->DiscoverCommissionableNodes(filter);
}

Expand Down
55 changes: 40 additions & 15 deletions src/lib/mdns/Advertiser.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <core/PeerId.h>
#include <inet/InetLayer.h>
#include <lib/support/Span.h>
#include <support/CHIPMemString.h>

namespace chip {
namespace Mdns {
Expand Down Expand Up @@ -179,34 +180,55 @@ class CommissionAdvertisingParameters : public BaseAdvertisingParams<CommissionA
{
if (deviceName.HasValue())
{
strncpy(sDeviceName, deviceName.Value(), min(strlen(deviceName.Value()) + 1, sizeof(sDeviceName)));
mDeviceName = Optional<const char *>::Value(static_cast<const char *>(sDeviceName));
chip::Platform::CopyString(mDeviceName, sizeof(mDeviceName), deviceName.Value());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
chip::Platform::CopyString(mDeviceName, sizeof(mDeviceName), deviceName.Value());
Platform::CopyString(mDeviceName, sizeof(mDeviceName), deviceName.Value());

mDeviceNameHasValue = true;
}
else
{
mDeviceNameHasValue = false;
}
return *this;
}
Optional<const char *> GetDeviceName() const { return mDeviceName; }
Optional<const char *> GetDeviceName() const
{
return mDeviceNameHasValue ? Optional<const char *>::Value(mDeviceName) : Optional<const char *>::Missing();
}

CommissionAdvertisingParameters & SetRotatingId(Optional<const char *> rotatingId)
{
if (rotatingId.HasValue())
{
strncpy(sRotatingId, rotatingId.Value(), min(strlen(rotatingId.Value()) + 1, sizeof(sRotatingId)));
mRotatingId = Optional<const char *>::Value(static_cast<const char *>(sRotatingId));
chip::Platform::CopyString(mRotatingId, sizeof(mRotatingId), rotatingId.Value());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
chip::Platform::CopyString(mRotatingId, sizeof(mRotatingId), rotatingId.Value());
Platform::CopyString(mRotatingId, sizeof(mRotatingId), rotatingId.Value());

mRotatingIdHasValue = true;
}
else
{
mRotatingIdHasValue = false;
}
return *this;
}
Optional<const char *> GetRotatingId() const { return mRotatingId; }
Optional<const char *> GetRotatingId() const
{
return mRotatingIdHasValue ? Optional<const char *>::Value(mRotatingId) : Optional<const char *>::Missing();
}

CommissionAdvertisingParameters & SetPairingInstr(Optional<const char *> pairingInstr)
{
if (pairingInstr.HasValue())
{
strncpy(sPairingInstr, pairingInstr.Value(), min(strlen(pairingInstr.Value()) + 1, sizeof(sPairingInstr)));
mPairingInstr = Optional<const char *>::Value(static_cast<const char *>(sPairingInstr));
chip::Platform::CopyString(mPairingInstr, sizeof(mPairingInstr), pairingInstr.Value());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
chip::Platform::CopyString(mPairingInstr, sizeof(mPairingInstr), pairingInstr.Value());
Platform::CopyString(mPairingInstr, sizeof(mPairingInstr), pairingInstr.Value());

mPairingInstrHasValue = true;
}
else
{
mPairingInstrHasValue = false;
}
return *this;
}
Optional<const char *> GetPairingInstr() const { return mPairingInstr; }
Optional<const char *> GetPairingInstr() const
{
return mPairingInstrHasValue ? Optional<const char *>::Value(mPairingInstr) : Optional<const char *>::Missing();
}

CommissionAdvertisingParameters & SetPairingHint(Optional<uint16_t> pairingHint)
{
Expand All @@ -233,14 +255,14 @@ class CommissionAdvertisingParameters : public BaseAdvertisingParams<CommissionA
chip::Optional<uint16_t> mDeviceType;
chip::Optional<uint16_t> mPairingHint;

char sDeviceName[kKeyDeviceNameMaxLength + 1];
chip::Optional<const char *> mDeviceName;
char mDeviceName[kKeyDeviceNameMaxLength + 1];
bool mDeviceNameHasValue = false;

char sRotatingId[kKeyRotatingIdMaxLength + 1];
chip::Optional<const char *> mRotatingId;
char mRotatingId[kKeyRotatingIdMaxLength + 1];
bool mRotatingIdHasValue = false;

char sPairingInstr[kKeyPairingInstructionMaxLength + 1];
chip::Optional<const char *> mPairingInstr;
char mPairingInstr[kKeyPairingInstructionMaxLength + 1];
bool mPairingInstrHasValue = false;
};

/// Handles advertising of CHIP nodes
Expand All @@ -264,6 +286,9 @@ class ServiceAdvertiser

/// Provides the system-wide implementation of the service advertiser
static ServiceAdvertiser & Instance();

/// Returns DNS-SD instance name formatted as hex string
virtual CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) = 0;
};

} // namespace Mdns
Expand Down
48 changes: 33 additions & 15 deletions src/lib/mdns/Advertiser_ImplMinimalMdns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class AdvertiserMinMdns : public ServiceAdvertiser,
CHIP_ERROR Advertise(const OperationalAdvertisingParameters & params) override;
CHIP_ERROR Advertise(const CommissionAdvertisingParameters & params) override;
CHIP_ERROR StopPublishDevice() override;
CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) override;

// MdnsPacketDelegate
void OnMdnsPacketData(const BytesRange & data, const chip::Inet::IPPacketInfo * info) override;
Expand Down Expand Up @@ -146,6 +147,8 @@ class AdvertiserMinMdns : public ServiceAdvertiser,
QueryResponderAllocator<kMaxCommissionRecords> mQueryResponderAllocatorCommissioner;

ResponseSender mResponseSender;
uint32_t mCommissionInstanceName1;
uint32_t mCommissionInstanceName2;

// current request handling
const chip::Inet::IPPacketInfo * mCurrentSource = nullptr;
Expand Down Expand Up @@ -191,6 +194,9 @@ CHIP_ERROR AdvertiserMinMdns::Start(chip::Inet::InetLayer * inetLayer, uint16_t
{
GlobalMinimalMdnsServer::Server().Shutdown();

mCommissionInstanceName1 = GetRandU32();
mCommissionInstanceName2 = GetRandU32();

ReturnErrorOnFailure(GlobalMinimalMdnsServer::Instance().StartServer(inetLayer, port));

ChipLogProgress(Discovery, "CHIP minimal mDNS started advertising.");
Expand Down Expand Up @@ -277,8 +283,23 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const OperationalAdvertisingParameters &
return CHIP_NO_ERROR;
}

CHIP_ERROR AdvertiserMinMdns::GetCommissionableInstanceName(char * instanceName, size_t maxLength)
{
if (maxLength < (kMaxInstanceNameSize + 1))
{
return CHIP_ERROR_NO_MEMORY;
}
size_t len = snprintf(instanceName, maxLength, ChipLogFormatX64, mCommissionInstanceName1, mCommissionInstanceName2);
if (len >= maxLength)
{
return CHIP_ERROR_NO_MEMORY;
}
return CHIP_NO_ERROR;
}

CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & params)
{

// TODO: When multi-admin is enabled, operational does not need to be cleared here.
if (params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissionableNode)
{
Expand All @@ -291,11 +312,8 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters &

// TODO: need to detect colisions here
char nameBuffer[64] = "";
size_t len = snprintf(nameBuffer, sizeof(nameBuffer), ChipLogFormatX64, GetRandU32(), GetRandU32());
if (len >= sizeof(nameBuffer))
{
return CHIP_ERROR_NO_MEMORY;
}
ReturnErrorOnFailure(GetCommissionableInstanceName(nameBuffer, sizeof(nameBuffer)));

QueryResponderAllocator<kMaxCommissionRecords> * allocator =
params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissionableNode ? &mQueryResponderAllocatorCommissionable
: &mQueryResponderAllocatorCommissioner;
Expand Down Expand Up @@ -486,26 +504,26 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis
char txtVidPid[chip::Mdns::kKeyVendorProductMaxLength + 4];
if (params.GetProductId().HasValue() && params.GetVendorId().HasValue())
{
sprintf(txtVidPid, "VP=%d+%d", params.GetVendorId().Value(), params.GetProductId().Value());
snprintf(txtVidPid, sizeof(txtVidPid), "VP=%d+%d", params.GetVendorId().Value(), params.GetProductId().Value());
txtFields[numTxtFields++] = txtVidPid;
}
else if (params.GetVendorId().HasValue())
{
sprintf(txtVidPid, "VP=%d", params.GetVendorId().Value());
snprintf(txtVidPid, sizeof(txtVidPid), "VP=%d", params.GetVendorId().Value());
txtFields[numTxtFields++] = txtVidPid;
}

char txtDeviceType[chip::Mdns::kKeyDeviceTypeMaxLength + 4];
if (params.GetDeviceType().HasValue())
{
sprintf(txtDeviceType, "DT=%d", params.GetDeviceType().Value());
snprintf(txtDeviceType, sizeof(txtDeviceType), "DT=%d", params.GetDeviceType().Value());
txtFields[numTxtFields++] = txtDeviceType;
}

char txtDeviceName[chip::Mdns::kKeyDeviceNameMaxLength + 4];
if (params.GetDeviceName().HasValue())
{
sprintf(txtDeviceName, "DN=%s", params.GetDeviceName().Value());
snprintf(txtDeviceName, sizeof(txtDeviceName), "DN=%s", params.GetDeviceName().Value());
txtFields[numTxtFields++] = txtDeviceName;
}

Expand All @@ -514,7 +532,7 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis
{
// a discriminator always exists
char txtDiscriminator[chip::Mdns::kKeyDiscriminatorMaxLength + 3];
sprintf(txtDiscriminator, "D=%d", params.GetLongDiscriminator());
snprintf(txtDiscriminator, sizeof(txtDiscriminator), "D=%d", params.GetLongDiscriminator());
txtFields[numTxtFields++] = txtDiscriminator;

if (!params.GetVendorId().HasValue())
Expand All @@ -523,34 +541,34 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis
}

char txtCommissioningMode[chip::Mdns::kKeyCommissioningModeMaxLength + 4];
sprintf(txtCommissioningMode, "CM=%d", params.GetCommissioningMode() ? 1 : 0);
snprintf(txtCommissioningMode, sizeof(txtCommissioningMode), "CM=%d", params.GetCommissioningMode() ? 1 : 0);
txtFields[numTxtFields++] = txtCommissioningMode;

char txtOpenWindowCommissioningMode[chip::Mdns::kKeyAdditionalPairingMaxLength + 4];
if (params.GetCommissioningMode() && params.GetOpenWindowCommissioningMode())
{
sprintf(txtOpenWindowCommissioningMode, "AP=1");
snprintf(txtOpenWindowCommissioningMode, sizeof(txtOpenWindowCommissioningMode), "AP=1");
txtFields[numTxtFields++] = txtOpenWindowCommissioningMode;
}

char txtRotatingDeviceId[chip::Mdns::kKeyRotatingIdMaxLength + 4];
if (params.GetRotatingId().HasValue())
{
sprintf(txtRotatingDeviceId, "RI=%s", params.GetRotatingId().Value());
snprintf(txtRotatingDeviceId, sizeof(txtRotatingDeviceId), "RI=%s", params.GetRotatingId().Value());
txtFields[numTxtFields++] = txtRotatingDeviceId;
}

char txtPairingHint[chip::Mdns::kKeyPairingInstructionMaxLength + 4];
if (params.GetPairingHint().HasValue())
{
sprintf(txtPairingHint, "PH=%d", params.GetPairingHint().Value());
snprintf(txtPairingHint, sizeof(txtPairingHint), "PH=%d", params.GetPairingHint().Value());
txtFields[numTxtFields++] = txtPairingHint;
}

char txtPairingInstr[chip::Mdns::kKeyPairingInstructionMaxLength + 4];
if (params.GetPairingInstr().HasValue())
{
sprintf(txtPairingInstr, "PI=%s", params.GetPairingInstr().Value());
snprintf(txtPairingInstr, sizeof(txtPairingInstr), "PI=%s", params.GetPairingInstr().Value());
txtFields[numTxtFields++] = txtPairingInstr;
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/lib/mdns/Advertiser_ImplNone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class NoneAdvertiser : public ServiceAdvertiser
ChipLogError(Discovery, "mDNS advertising not available. mDNS stop not available.");
return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) override
{
ChipLogError(Discovery, "mDNS advertising not available. mDNS GetCommissionableInstanceName not available.");
return CHIP_ERROR_NOT_IMPLEMENTED;
}
};

NoneAdvertiser gAdvertiser;
Expand Down
19 changes: 17 additions & 2 deletions src/lib/mdns/Discovery_ImplPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,21 @@ void DiscoveryImplPlatform::HandleMdnsError(void * context, CHIP_ERROR error)
}
}

CHIP_ERROR DiscoveryImplPlatform::GetCommissionableInstanceName(char * instanceName, size_t maxLength)
{
if (maxLength < (chip::Mdns::kMaxInstanceNameSize + 1))
{
return CHIP_ERROR_NO_MEMORY;
}
size_t len = snprintf(instanceName, maxLength, "%08" PRIX32 "%08" PRIX32, static_cast<uint32_t>(mCommissionInstanceName >> 32),
static_cast<uint32_t>(mCommissionInstanceName));
if (len >= maxLength)
{
return CHIP_ERROR_NO_MEMORY;
}
return CHIP_NO_ERROR;
}

CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameters & params)
{
CHIP_ERROR error = CHIP_NO_ERROR;
Expand Down Expand Up @@ -143,8 +158,8 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter
return error;
}

snprintf(service.mName, sizeof(service.mName), "%08" PRIX32 "%08" PRIX32, static_cast<uint32_t>(mCommissionInstanceName >> 32),
static_cast<uint32_t>(mCommissionInstanceName));
ReturnErrorOnFailure(GetCommissionableInstanceName(service.mName, sizeof(service.mName)));

if (params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissionableNode)
{
strncpy(service.mType, kCommissionableServiceName, sizeof(service.mType));
Expand Down
3 changes: 3 additions & 0 deletions src/lib/mdns/Discovery_ImplPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver
/// This function stops publishing the device on mDNS.
CHIP_ERROR StopPublishDevice() override;

/// Returns DNS-SD instance name formatted as hex string
CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) override;

/// Registers a resolver delegate if none has been registered before
CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) override;

Expand Down
Loading