Skip to content

Commit

Permalink
Add a controller factory to vend controllers per Fabric (#9872)
Browse files Browse the repository at this point in the history
* Add a controller factory to vend controllers per Fabric

* Remove the UDP port from CHIPDeviceController and CHIPDevice

* fix style
  • Loading branch information
sagar-apple authored Sep 29, 2021
1 parent 1f0e8ba commit ae69dd7
Show file tree
Hide file tree
Showing 17 changed files with 728 additions and 312 deletions.
27 changes: 17 additions & 10 deletions examples/chip-tool/commands/common/Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <platform/CHIPDeviceLayer.h>
#endif

#include <controller/CHIPDeviceControllerFactory.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/DeviceAttestationVerifier.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
Expand All @@ -35,6 +36,8 @@
#include <lib/support/CodeUtils.h>
#include <lib/support/ScopedBuffer.h>

using DeviceControllerFactory = chip::Controller::DeviceControllerFactory;

void Commands::Register(const char * clusterName, commands_list commandsList)
{
for (auto & command : commandsList)
Expand All @@ -46,7 +49,8 @@ void Commands::Register(const char * clusterName, commands_list commandsList)
int Commands::Run(int argc, char ** argv)
{
CHIP_ERROR err = CHIP_NO_ERROR;
chip::Controller::CommissionerInitParams initParams;
chip::Controller::FactoryInitParams factoryInitParams;
chip::Controller::SetupParams commissionerParams;
Command * command = nullptr;
NodeId localId;
NodeId remoteId;
Expand All @@ -73,14 +77,14 @@ int Commands::Run(int argc, char ** argv)
ChipLogProgress(Controller, "Read local id 0x" ChipLogFormatX64 ", remote id 0x" ChipLogFormatX64, ChipLogValueX64(localId),
ChipLogValueX64(remoteId));

initParams.storageDelegate = &mStorage;
factoryInitParams.storageDelegate = &mStorage;
factoryInitParams.listenPort = mStorage.GetListenPort();

err = mOpCredsIssuer.Initialize(mStorage);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Operational Cred Issuer: %s", chip::ErrorStr(err)));

initParams.operationalCredentialsDelegate = &mOpCredsIssuer;
commissionerParams.operationalCredentialsDelegate = &mOpCredsIssuer;

err = mController.SetUdpListenPort(mStorage.GetListenPort());
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Commissioner: %s", chip::ErrorStr(err)));

chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());
Expand All @@ -104,19 +108,22 @@ int Commands::Run(int argc, char ** argv)
err = mOpCredsIssuer.GenerateNOCChainAfterValidation(localId, 0, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan);
SuccessOrExit(err);

initParams.ephemeralKeypair = &ephemeralKey;
initParams.controllerRCAC = rcacSpan;
initParams.controllerICAC = icacSpan;
initParams.controllerNOC = nocSpan;
commissionerParams.ephemeralKeypair = &ephemeralKey;
commissionerParams.controllerRCAC = rcacSpan;
commissionerParams.controllerICAC = icacSpan;
commissionerParams.controllerNOC = nocSpan;

err = mController.Init(initParams);
// init the factory, then setup the Controller
err = DeviceControllerFactory::GetInstance().Init(factoryInitParams);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Controller Factory failed to initialize"));
err = DeviceControllerFactory::GetInstance().SetupCommissioner(commissionerParams, mController);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Commissioner: %s", chip::ErrorStr(err)));
}

#if CONFIG_USE_SEPARATE_EVENTLOOP
// ServiceEvents() calls StartEventLoopTask(), which is paired with the
// StopEventLoopTask() below.
err = mController.ServiceEvents();
err = DeviceControllerFactory::GetInstance().ServiceEvents();
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Run Loop: %s", chip::ErrorStr(err)));
#endif // CONFIG_USE_SEPARATE_EVENTLOOP

Expand Down
25 changes: 16 additions & 9 deletions examples/ota-requestor-app/linux/ExampleSelfCommissioning.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#pragma once

#include <controller/CHIPDeviceController.h>
#include <controller/CHIPDeviceControllerFactory.h>
#include <controller/ExampleOperationalCredentialsIssuer.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
Expand All @@ -30,13 +30,14 @@ using chip::Controller::DeviceController;
using chip::Controller::ExampleOperationalCredentialsIssuer;

CHIP_ERROR DoExampleSelfCommissioning(DeviceController & controller, ExampleOperationalCredentialsIssuer * opCredsIssuer,
PersistentStorageDelegate * storage, chip::NodeId localNodeId)
PersistentStorageDelegate * storage, chip::NodeId localNodeId, uint16_t listenPort)
{
CHIP_ERROR err = CHIP_NO_ERROR;
chip::Platform::ScopedMemoryBuffer<uint8_t> noc;
chip::Platform::ScopedMemoryBuffer<uint8_t> icac;
chip::Platform::ScopedMemoryBuffer<uint8_t> rcac;
chip::Controller::ControllerInitParams initParams;
chip::Controller::FactoryInitParams initParams;
chip::Controller::SetupParams setupParams;

VerifyOrExit(storage != nullptr && opCredsIssuer != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);

Expand All @@ -61,15 +62,21 @@ CHIP_ERROR DoExampleSelfCommissioning(DeviceController & controller, ExampleOper
err = opCredsIssuer->GenerateNOCChainAfterValidation(localNodeId, 0, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan);
SuccessOrExit(err);

initParams.ephemeralKeypair = &ephemeralKey;
initParams.controllerRCAC = rcacSpan;
initParams.controllerICAC = icacSpan;
initParams.controllerNOC = nocSpan;
initParams.operationalCredentialsDelegate = opCredsIssuer;
setupParams.ephemeralKeypair = &ephemeralKey;
setupParams.controllerRCAC = rcacSpan;
setupParams.controllerICAC = icacSpan;
setupParams.controllerNOC = nocSpan;
setupParams.operationalCredentialsDelegate = opCredsIssuer;

initParams.storageDelegate = storage;
initParams.listenPort = listenPort;

err = controller.Init(initParams);
auto & factory = chip::Controller::DeviceControllerFactory::GetInstance();

err = factory.Init(initParams);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Controller Factory init failure! %s", chip::ErrorStr(err)));

err = factory.SetupController(setupParams, controller);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Controller init failure! %s", chip::ErrorStr(err)));
}

Expand Down
7 changes: 3 additions & 4 deletions examples/ota-requestor-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <app-common/zap-generated/enums.h>
#include <app/util/util.h>
#include <controller/CHIPDevice.h>
#include <controller/CHIPDeviceController.h>
#include <controller/CHIPDeviceControllerFactory.h>
#include <controller/ExampleOperationalCredentialsIssuer.h>
#include <lib/core/CHIPError.h>
#include <lib/support/CHIPArgParser.hpp>
Expand Down Expand Up @@ -229,17 +229,16 @@ int main(int argc, char * argv[])

chip::Logging::SetLogFilter(mStorage.GetLoggingLevel());

err = mController.SetUdpListenPort(mStorage.GetListenPort());
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "failed to set UDP port: %s", chip::ErrorStr(err)));

// Until #9518 is fixed, the only way to open a CASE session to another node is to commission it first using the
// DeviceController API. Thus, the ota-requestor-app must do self commissioning and then read CASE credentials from persistent
// storage to connect to the Provider node. See README.md for instructions.
// NOTE: Controller is initialized in this call
err = DoExampleSelfCommissioning(mController, &mOpCredsIssuer, &mStorage, mStorage.GetLocalNodeId());
err = DoExampleSelfCommissioning(mController, &mOpCredsIssuer, &mStorage, mStorage.GetLocalNodeId(), mStorage.GetListenPort());
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(SoftwareUpdate, "example self-commissioning failed: %s", chip::ErrorStr(err)));

err = mController.ServiceEvents();
err = chip::Controller::DeviceControllerFactory::GetInstance().ServiceEvents();
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "ServiceEvents() failed: %s", chip::ErrorStr(err)));

ChipLogProgress(SoftwareUpdate, "Attempting to connect to device 0x%" PRIX64, providerNodeId);
Expand Down
17 changes: 10 additions & 7 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
#include <ControllerShellCommands.h>
#include <controller/CHIPDeviceController.h>
#include <controller/CHIPDeviceControllerFactory.h>
#include <controller/ExampleOperationalCredentialsIssuer.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
#include <platform/KeyValueStoreManager.h>
Expand Down Expand Up @@ -212,16 +212,17 @@ CHIP_ERROR InitCommissioner()
{
NodeId localId = chip::kPlaceholderNodeId;

chip::Controller::CommissionerInitParams params;
chip::Controller::FactoryInitParams factoryParams;
chip::Controller::SetupParams params;

params.storageDelegate = &gServerStorage;
params.mDeviceAddressUpdateDelegate = nullptr;
factoryParams.storageDelegate = &gServerStorage;
// use a different listen port for the commissioner.
factoryParams.listenPort = LinuxDeviceOptions::GetInstance().securedCommissionerPort;
params.deviceAddressUpdateDelegate = nullptr;
params.operationalCredentialsDelegate = &gOpCredsIssuer;

ReturnErrorOnFailure(gOpCredsIssuer.Initialize(gServerStorage));

// use a different listen port for the commissioner.
ReturnErrorOnFailure(gCommissioner.SetUdpListenPort(LinuxDeviceOptions::GetInstance().securedCommissionerPort));
// No need to explicitly set the UDC port since we will use default
ReturnErrorOnFailure(gCommissioner.SetUdcListenPort(LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort));

Expand Down Expand Up @@ -251,7 +252,9 @@ CHIP_ERROR InitCommissioner()
params.controllerICAC = icacSpan;
params.controllerNOC = nocSpan;

ReturnErrorOnFailure(gCommissioner.Init(params));
auto & factory = chip::Controller::DeviceControllerFactory::GetInstance();
ReturnErrorOnFailure(factory.Init(factoryParams));
ReturnErrorOnFailure(factory.SetupCommissioner(params, gCommissioner));

return CHIP_NO_ERROR;
}
Expand Down
2 changes: 2 additions & 0 deletions src/controller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ static_library("controller") {
"CHIPDevice.h",
"CHIPDeviceController.cpp",
"CHIPDeviceController.h",
"CHIPDeviceControllerFactory.cpp",
"CHIPDeviceControllerFactory.h",
"DeviceAddressUpdateDelegate.h",
"EmptyDataModelHandler.cpp",
"ExampleOperationalCredentialsIssuer.cpp",
Expand Down
12 changes: 3 additions & 9 deletions src/controller/CHIPDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,13 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta
* still using them, it can lead to unknown behavior and crashes.
*
* @param[in] params Wrapper object for transport manager etc.
* @param[in] listenPort Port on which controller is listening (typically CHIP_PORT)
* @param[in] fabric Local administrator that's initializing this device object
*/
void Init(ControllerDeviceInitParams params, uint16_t listenPort, FabricIndex fabric)
void Init(ControllerDeviceInitParams params, FabricIndex fabric)
{
mSessionManager = params.sessionManager;
mExchangeMgr = params.exchangeMgr;
mInetLayer = params.inetLayer;
mListenPort = listenPort;
mFabricIndex = fabric;
mStorageDelegate = params.storageDelegate;
mIDAllocator = params.idAllocator;
Expand All @@ -196,15 +194,13 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta
* is actually paired.
*
* @param[in] params Wrapper object for transport manager etc.
* @param[in] listenPort Port on which controller is listening (typically CHIP_PORT)
* @param[in] deviceId Node ID of the device
* @param[in] peerAddress The location of the peer. MUST be of type Transport::Type::kUdp
* @param[in] fabric Local administrator that's initializing this device object
*/
void Init(ControllerDeviceInitParams params, uint16_t listenPort, NodeId deviceId, const Transport::PeerAddress & peerAddress,
FabricIndex fabric)
void Init(ControllerDeviceInitParams params, NodeId deviceId, const Transport::PeerAddress & peerAddress, FabricIndex fabric)
{
Init(params, mListenPort, fabric);
Init(params, fabric);
mDeviceId = deviceId;
mState = ConnectionState::Connecting;

Expand Down Expand Up @@ -522,8 +518,6 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta
static void OnOpenPairingWindowSuccessResponse(void * context);
static void OnOpenPairingWindowFailureResponse(void * context, uint8_t status);

uint16_t mListenPort;

FabricIndex mFabricIndex = Transport::kUndefinedFabricIndex;

Transport::FabricTable * mFabricsTable = nullptr;
Expand Down
Loading

0 comments on commit ae69dd7

Please sign in to comment.