Skip to content

Commit

Permalink
implement cluster logic
Browse files Browse the repository at this point in the history
  • Loading branch information
pan-apple committed Jul 28, 2021
1 parent 1a921f4 commit 3e93028
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 161 deletions.
2 changes: 1 addition & 1 deletion examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ class SetupListModel : public ListScreen::Model
else if (i == 2)
{
app::Mdns::AdvertiseCommissionableNode();
OpenDefaultPairingWindow(ResetFabrics::kYes, PairingWindowAdvertisement::kMdns);
OpenDefaultPairingWindow(ResetFabrics::kYes, kNoCommissioningTimeout, PairingWindowAdvertisement::kMdns);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,9 @@
***************************************************************************/

#include <app/CommandHandler.h>
#include <app/common/gen/af-structs.h>
#include <app/common/gen/attribute-id.h>
#include <app/common/gen/attribute-type.h>
#include <app/common/gen/cluster-id.h>
#include <app/common/gen/command-id.h>
#include <app/server/Server.h>
#include <app/util/af.h>
#include <support/CodeUtils.h>
#include <support/ScopedBuffer.h>
#include <support/logging/CHIPLogging.h>

using namespace chip;
Expand All @@ -39,22 +33,50 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback(app
uint16_t Discriminator, uint32_t Iterations,
ByteSpan Salt, uint16_t PasscodeID)
{
EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE;
EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
PASEVerifier verifier;
ChipLogProgress(Zcl, "Received command to open commissioning window");
VerifyOrExit(!IsPairingWindowOpen(), status = EMBER_ZCL_STATUS_FAILURE);
VerifyOrExit(sizeof(verifier) == PAKEVerifier.size(), status = EMBER_ZCL_STATUS_FAILURE);
memcpy(&verifier[0][0], PAKEVerifier.data(), PAKEVerifier.size());
VerifyOrExit(OpenPairingWindowUsingVerifier(CommissioningTimeout, Discriminator, verifier, Iterations, Salt, PasscodeID) ==
CHIP_NO_ERROR,
status = EMBER_ZCL_STATUS_FAILURE);
ChipLogProgress(Zcl, "Commissioning window is now open");

exit:
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
ChipLogError(Zcl, "Failed to open commissioning window. Status %d", status);
}
emberAfSendImmediateDefaultResponse(status);
return true;
}

bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallback(app::CommandHandler * commandObj,
uint16_t CommissioningTimeout)
{
EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE;
EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
ChipLogProgress(Zcl, "Received command to open basic commissioning window");
VerifyOrExit(!IsPairingWindowOpen(), status = EMBER_ZCL_STATUS_FAILURE);
VerifyOrExit(OpenDefaultPairingWindow(ResetFabrics::kNo, CommissioningTimeout) == CHIP_NO_ERROR,
status = EMBER_ZCL_STATUS_FAILURE);
ChipLogProgress(Zcl, "Commissioning window is now open");

exit:
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
ChipLogError(Zcl, "Failed to open commissioning window. Status %d", status);
}
emberAfSendImmediateDefaultResponse(status);
return true;
}

bool emberAfAdministratorCommissioningClusterRevokeCommissioningCallback(app::CommandHandler * commandObj)
{
EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE;
emberAfSendImmediateDefaultResponse(status);
ChipLogProgress(Zcl, "Received command to close commissioning window");
ClosePairingWindow();
ChipLogProgress(Zcl, "Commissioning window is now closed");
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
}
12 changes: 5 additions & 7 deletions src/app/server/RendezvousServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ void OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t
server->OnPlatformEvent(event);
}
} // namespace
static constexpr uint32_t kSpake2p_Iteration_Count = 100;
static const char * kSpake2pKeyExchangeSalt = "SPAKE2P Key Salt";

void RendezvousServer::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * event)
{
Expand All @@ -67,7 +65,8 @@ void RendezvousServer::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * even
}
}

CHIP_ERROR RendezvousServer::WaitForPairing(const RendezvousParameters & params, Messaging::ExchangeManager * exchangeManager,
CHIP_ERROR RendezvousServer::WaitForPairing(const RendezvousParameters & params, uint32_t pbkdf2IterCount, const ByteSpan & salt,
uint16_t passcodeID, Messaging::ExchangeManager * exchangeManager,
TransportMgrBase * transportMgr, SecureSessionMgr * sessionMgr,
Transport::FabricInfo * fabric)
{
Expand Down Expand Up @@ -106,13 +105,12 @@ CHIP_ERROR RendezvousServer::WaitForPairing(const RendezvousParameters & params,

if (params.HasPASEVerifier())
{
ReturnErrorOnFailure(mPairingSession.WaitForPairing(params.GetPASEVerifier(), keyID, this));
ReturnErrorOnFailure(
mPairingSession.WaitForPairing(params.GetPASEVerifier(), pbkdf2IterCount, salt, passcodeID, keyID, this));
}
else
{
ReturnErrorOnFailure(mPairingSession.WaitForPairing(params.GetSetupPINCode(), kSpake2p_Iteration_Count,
reinterpret_cast<const unsigned char *>(kSpake2pKeyExchangeSalt),
strlen(kSpake2pKeyExchangeSalt), keyID, this));
ReturnErrorOnFailure(mPairingSession.WaitForPairing(params.GetSetupPINCode(), pbkdf2IterCount, salt, keyID, this));
}

ReturnErrorOnFailure(mPairingSession.MessageDispatch().Init(transportMgr));
Expand Down
5 changes: 3 additions & 2 deletions src/app/server/RendezvousServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ namespace chip {
class RendezvousServer : public SessionEstablishmentDelegate
{
public:
CHIP_ERROR WaitForPairing(const RendezvousParameters & params, Messaging::ExchangeManager * exchangeManager,
TransportMgrBase * transportMgr, SecureSessionMgr * sessionMgr, Transport::FabricInfo * fabric);
CHIP_ERROR WaitForPairing(const RendezvousParameters & params, uint32_t pbkdf2IterCount, const ByteSpan & salt,
uint16_t passcodeID, Messaging::ExchangeManager * exchangeManager, TransportMgrBase * transportMgr,
SecureSessionMgr * sessionMgr, Transport::FabricInfo * fabric);

CHIP_ERROR Init(AppDelegate * delegate, PersistentStorageDelegate * storage, SessionIDAllocator * idAllocator)
{
Expand Down
142 changes: 71 additions & 71 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ class DeviceDiscriminatorCache
DeviceDiscriminatorCache gDeviceDiscriminatorCache;
FabricTable gFabrics;
FabricIndex gNextAvailableFabricIndex = 0;
bool gPairingWindowOpen = false;

class ServerRendezvousAdvertisementDelegate : public RendezvousAdvertisementDelegate
{
Expand All @@ -261,12 +262,15 @@ class ServerRendezvousAdvertisementDelegate : public RendezvousAdvertisementDele
{
mDelegate->OnPairingWindowOpened();
}
gPairingWindowOpen = true;
return CHIP_NO_ERROR;
}
CHIP_ERROR StopAdvertisement() const override
{
gDeviceDiscriminatorCache.RestoreDiscriminator();

gPairingWindowOpen = false;

if (isBLE)
{
ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false));
Expand Down Expand Up @@ -303,29 +307,6 @@ CASEServer gCASEServer;
Messaging::ExchangeManager gExchangeMgr;
ServerRendezvousAdvertisementDelegate gAdvDelegate;

static CHIP_ERROR OpenPairingWindowUsingVerifier(uint16_t discriminator, PASEVerifier & verifier)
{
RendezvousParameters params;

ReturnErrorOnFailure(gDeviceDiscriminatorCache.UpdateDiscriminator(discriminator));

#if CONFIG_NETWORK_LAYER_BLE
params.SetPASEVerifier(verifier)
.SetBleLayer(DeviceLayer::ConnectivityMgr().GetBleLayer())
.SetPeerAddress(Transport::PeerAddress::BLE())
.SetAdvertisementDelegate(&gAdvDelegate);
#else
params.SetPASEVerifier(verifier);
#endif // CONFIG_NETWORK_LAYER_BLE

FabricIndex fabricIndex = gNextAvailableFabricIndex;
FabricInfo * fabricInfo = gFabrics.AssignFabricIndex(fabricIndex);
VerifyOrReturnError(fabricInfo != nullptr, CHIP_ERROR_NO_MEMORY);
gNextAvailableFabricIndex++;

return gRendezvousServer.WaitForPairing(std::move(params), &gExchangeMgr, &gTransports, &gSessions, fabricInfo);
}

class ServerCallback : public ExchangeDelegate
{
public:
Expand All @@ -345,52 +326,7 @@ class ServerCallback : public ExchangeDelegate
ChipLogProgress(AppServer, "Packet received from Node 0x" ChipLogFormatX64 ": %u bytes",
ChipLogValueX64(packetHeader.GetSourceNodeId().Value()), buffer->DataLength());

// TODO: This code is temporary, and must be updated to use the Cluster API.
// Issue: https://github.com/project-chip/connectedhomeip/issues/4725
if (payloadHeader.HasProtocol(chip::Protocols::ServiceProvisioning::Id))
{
uint32_t timeout;
uint16_t discriminator;
PASEVerifier verifier;

ChipLogProgress(AppServer, "Received service provisioning message. Treating it as OpenPairingWindow request");
chip::System::PacketBufferTLVReader reader;
reader.Init(std::move(buffer));
reader.ImplicitProfileId = chip::Protocols::ServiceProvisioning::Id.ToTLVProfileId();

SuccessOrExit(reader.Next(kTLVType_UnsignedInteger, TLV::ProfileTag(reader.ImplicitProfileId, 1)));
SuccessOrExit(reader.Get(timeout));

err = reader.Next(kTLVType_UnsignedInteger, TLV::ProfileTag(reader.ImplicitProfileId, 2));
if (err == CHIP_NO_ERROR)
{
SuccessOrExit(reader.Get(discriminator));

err = reader.Next(kTLVType_ByteString, TLV::ProfileTag(reader.ImplicitProfileId, 3));
if (err == CHIP_NO_ERROR)
{
SuccessOrExit(reader.GetBytes(reinterpret_cast<uint8_t *>(verifier), sizeof(verifier)));
}
}

ChipLogProgress(AppServer, "Pairing Window timeout %" PRIu32 " seconds", timeout);

if (err != CHIP_NO_ERROR)
{
SuccessOrExit(err = OpenDefaultPairingWindow(ResetFabrics::kNo));
}
else
{
ChipLogProgress(AppServer, "Pairing Window discriminator %d", discriminator);
err = OpenPairingWindowUsingVerifier(discriminator, verifier);
SuccessOrExit(err);
}
ChipLogProgress(AppServer, "Opened the pairing window");
}
else
{
HandleDataModelMessage(exchangeContext, std::move(buffer));
}
HandleDataModelMessage(exchangeContext, std::move(buffer));

exit:
return err;
Expand Down Expand Up @@ -423,9 +359,15 @@ chip::Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient gUDC

#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT

void HandlePairingWindowTimeout(System::Layer * aSystemLayer, void * aAppState, CHIP_ERROR aError)
{
ClosePairingWindow();
}

} // namespace

CHIP_ERROR OpenDefaultPairingWindow(ResetFabrics resetFabrics, chip::PairingWindowAdvertisement advertisementMode)
CHIP_ERROR OpenDefaultPairingWindow(ResetFabrics resetFabrics, uint16_t commissioningTimeoutSeconds,
chip::PairingWindowAdvertisement advertisementMode)
{
// TODO(cecille): If this is re-called when the window is already open, what should happen?
gDeviceDiscriminatorCache.RestoreDiscriminator();
Expand Down Expand Up @@ -460,7 +402,65 @@ CHIP_ERROR OpenDefaultPairingWindow(ResetFabrics resetFabrics, chip::PairingWind
VerifyOrReturnError(fabricInfo != nullptr, CHIP_ERROR_NO_MEMORY);
gNextAvailableFabricIndex++;

return gRendezvousServer.WaitForPairing(std::move(params), &gExchangeMgr, &gTransports, &gSessions, fabricInfo);
ReturnErrorOnFailure(gRendezvousServer.WaitForPairing(
std::move(params), kSpake2p_Iteration_Count,
ByteSpan(reinterpret_cast<const unsigned char *>(kSpake2pKeyExchangeSalt), strlen(kSpake2pKeyExchangeSalt)), 0,
&gExchangeMgr, &gTransports, &gSessions, fabricInfo));

if (commissioningTimeoutSeconds != kNoCommissioningTimeout)
{
ReturnErrorOnFailure(
DeviceLayer::SystemLayer.StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr));
}

return CHIP_NO_ERROR;
}

CHIP_ERROR OpenPairingWindowUsingVerifier(uint16_t commissioningTimeoutSeconds, uint16_t discriminator, PASEVerifier & verifier,
uint32_t iterations, ByteSpan salt, uint16_t passcodeID)
{
RendezvousParameters params;

ReturnErrorOnFailure(gDeviceDiscriminatorCache.UpdateDiscriminator(discriminator));

#if CONFIG_NETWORK_LAYER_BLE
params.SetPASEVerifier(verifier)
.SetBleLayer(DeviceLayer::ConnectivityMgr().GetBleLayer())
.SetPeerAddress(Transport::PeerAddress::BLE())
.SetAdvertisementDelegate(&gAdvDelegate);
#else
params.SetPASEVerifier(verifier);
#endif // CONFIG_NETWORK_LAYER_BLE

FabricIndex fabricIndex = gNextAvailableFabricIndex;
FabricInfo * fabricInfo = gFabrics.AssignFabricIndex(fabricIndex);
VerifyOrReturnError(fabricInfo != nullptr, CHIP_ERROR_NO_MEMORY);
gNextAvailableFabricIndex++;

ReturnErrorOnFailure(gRendezvousServer.WaitForPairing(std::move(params), iterations, salt, passcodeID, &gExchangeMgr,
&gTransports, &gSessions, fabricInfo));

if (commissioningTimeoutSeconds != kNoCommissioningTimeout)
{
ReturnErrorOnFailure(
DeviceLayer::SystemLayer.StartTimer(commissioningTimeoutSeconds * 1000, HandlePairingWindowTimeout, nullptr));
}

return CHIP_NO_ERROR;
}

void ClosePairingWindow()
{
if (gPairingWindowOpen)
{
ChipLogProgress(AppServer, "Closing pairing window");
gRendezvousServer.Cleanup();
}
}

bool IsPairingWindowOpen()
{
return gPairingWindowOpen;
}

// The function will initialize datamodel handler and then start the server
Expand Down
13 changes: 12 additions & 1 deletion src/app/server/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <app/server/AppDelegate.h>
#include <inet/InetConfig.h>
#include <messaging/ExchangeMgr.h>
#include <protocols/secure_channel/PASESession.h>
#include <transport/FabricTable.h>
#include <transport/SecureSessionMgr.h>
#include <transport/TransportMgr.h>
Expand Down Expand Up @@ -71,8 +72,18 @@ enum class PairingWindowAdvertisement

} // namespace chip

constexpr uint16_t kNoCommissioningTimeout = UINT16_MAX;

/**
* Open the pairing window using default configured parameters.
*/
CHIP_ERROR OpenDefaultPairingWindow(chip::ResetFabrics resetFabrics,
CHIP_ERROR OpenDefaultPairingWindow(chip::ResetFabrics resetFabrics, uint16_t commissioningTimeoutSeconds = kNoCommissioningTimeout,
chip::PairingWindowAdvertisement advertisementMode = chip::PairingWindowAdvertisement::kBle);

CHIP_ERROR OpenPairingWindowUsingVerifier(uint16_t commissioningTimeoutSeconds, uint16_t discriminator,
chip::PASEVerifier & verifier, uint32_t iterations, chip::ByteSpan salt,
uint16_t passcodeID);

void ClosePairingWindow();

bool IsPairingWindowOpen();
Loading

0 comments on commit 3e93028

Please sign in to comment.