| /* |
| * |
| * Copyright (c) 2020-2021 Project CHIP Authors |
| * Copyright (c) 2013-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * Declaration of CHIP Device Controller, a common class |
| * that implements connecting and messaging and will later |
| * be expanded to support discovery, pairing and |
| * provisioning of CHIP devices. |
| * |
| */ |
| |
| #pragma once |
| |
| #include <app/CASESessionManager.h> |
| #include <app/DeviceControllerInteractionModelDelegate.h> |
| #include <app/InteractionModelDelegate.h> |
| #include <app/OperationalDeviceProxy.h> |
| #include <controller-clusters/zap-generated/CHIPClientCallbacks.h> |
| #include <controller/AbstractDnssdDiscoveryController.h> |
| #include <controller/CHIPDeviceControllerSystemState.h> |
| #include <controller/CommissioneeDeviceProxy.h> |
| #include <controller/OperationalCredentialsDelegate.h> |
| #include <controller/SetUpCodePairer.h> |
| #include <credentials/DeviceAttestationVerifier.h> |
| #include <lib/core/CHIPConfig.h> |
| #include <lib/core/CHIPCore.h> |
| #include <lib/core/CHIPPersistentStorageDelegate.h> |
| #include <lib/core/CHIPTLV.h> |
| #include <lib/support/DLLUtil.h> |
| #include <lib/support/Pool.h> |
| #include <lib/support/SerializableIntegerSet.h> |
| #include <lib/support/Span.h> |
| #include <messaging/ExchangeMgr.h> |
| #include <protocols/secure_channel/MessageCounterManager.h> |
| #include <protocols/secure_channel/RendezvousParameters.h> |
| #include <protocols/user_directed_commissioning/UserDirectedCommissioning.h> |
| #include <transport/FabricTable.h> |
| #include <transport/SessionManager.h> |
| #include <transport/TransportMgr.h> |
| #include <transport/raw/UDP.h> |
| |
| #include <controller/CHIPDeviceControllerSystemState.h> |
| |
| #if CONFIG_DEVICE_LAYER |
| #include <platform/CHIPDeviceLayer.h> |
| #endif |
| |
| #if CONFIG_NETWORK_LAYER_BLE |
| #include <ble/BleLayer.h> |
| #endif |
| #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| #include <controller/DeviceAddressUpdateDelegate.h> |
| #include <controller/DeviceDiscoveryDelegate.h> |
| #include <lib/dnssd/Resolver.h> |
| #endif |
| |
| namespace chip { |
| |
| namespace Controller { |
| |
| using namespace chip::Protocols::UserDirectedCommissioning; |
| |
| constexpr uint16_t kNumMaxActiveDevices = CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES; |
| constexpr uint16_t kNumMaxPairedDevices = 128; |
| |
| // Raw functions for cluster callbacks |
| typedef void (*BasicSuccessCallback)(void * context, uint16_t val); |
| typedef void (*BasicFailureCallback)(void * context, uint8_t status); |
| void BasicSuccess(void * context, uint16_t val); |
| void BasicFailure(void * context, uint8_t status); |
| |
| struct ControllerInitParams |
| { |
| PersistentStorageDelegate * storageDelegate = nullptr; |
| DeviceControllerSystemState * systemState = nullptr; |
| #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| DeviceAddressUpdateDelegate * deviceAddressUpdateDelegate = nullptr; |
| DeviceDiscoveryDelegate * deviceDiscoveryDelegate = nullptr; |
| #endif |
| OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr; |
| |
| /* The following keypair must correspond to the public key used for generating |
| controllerNOC. It's used by controller to establish CASE sessions with devices */ |
| Crypto::P256Keypair * ephemeralKeypair = nullptr; |
| |
| /* The following certificates must be in x509 DER format */ |
| ByteSpan controllerNOC; |
| ByteSpan controllerICAC; |
| ByteSpan controllerRCAC; |
| |
| uint16_t controllerVendorId; |
| |
| FabricId fabricId = kUndefinedFabricId; |
| }; |
| |
| enum CommissioningStage : uint8_t |
| { |
| kError, |
| kSecurePairing, |
| kArmFailsafe, |
| // kConfigTime, // NOT YET IMPLEMENTED |
| // kConfigTimeZone, // NOT YET IMPLEMENTED |
| // kConfigDST, // NOT YET IMPLEMENTED |
| kConfigRegulatory, |
| kDeviceAttestation, |
| kCheckCertificates, |
| kConfigACL, |
| kNetworkSetup, |
| kScanNetworks, // optional stage if network setup fails (not yet implemented) |
| kNetworkEnable, |
| kFindOperational, |
| kSendComplete, |
| kCleanup, |
| }; |
| |
| class DLL_EXPORT DevicePairingDelegate |
| { |
| public: |
| virtual ~DevicePairingDelegate() {} |
| |
| enum Status : uint8_t |
| { |
| SecurePairingSuccess = 0, |
| SecurePairingFailed, |
| }; |
| |
| /** |
| * @brief |
| * Called when the pairing reaches a certain stage. |
| * |
| * @param status Current status of pairing |
| */ |
| virtual void OnStatusUpdate(DevicePairingDelegate::Status status) {} |
| |
| /** |
| * @brief |
| * Called when the pairing is complete (with success or error) |
| * |
| * @param error Error cause, if any |
| */ |
| virtual void OnPairingComplete(CHIP_ERROR error) {} |
| |
| /** |
| * @brief |
| * Called when the pairing is deleted (with success or error) |
| * |
| * @param error Error cause, if any |
| */ |
| virtual void OnPairingDeleted(CHIP_ERROR error) {} |
| |
| /** |
| * Called when the commissioning process is complete (with success or error) |
| */ |
| virtual void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) {} |
| }; |
| |
| struct CommissionerInitParams : public ControllerInitParams |
| { |
| DevicePairingDelegate * pairingDelegate = nullptr; |
| }; |
| |
| typedef void (*OnOpenCommissioningWindow)(void * context, NodeId deviceId, CHIP_ERROR status, SetupPayload payload); |
| |
| /** |
| * @brief |
| * Controller applications can use this class to communicate with already paired CHIP devices. The |
| * application is required to provide access to the persistent storage, where the paired device information |
| * is stored. This object of this class can be initialized with the data from the storage (List of devices, |
| * and device pairing information for individual devices). Alternatively, this class can retrieve the |
| * relevant information when the application tries to communicate with the device |
| */ |
| class DLL_EXPORT DeviceController : public SessionReleaseDelegate, |
| #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| public AbstractDnssdDiscoveryController, |
| #endif |
| public app::InteractionModelDelegate |
| { |
| public: |
| DeviceController(); |
| virtual ~DeviceController() {} |
| |
| enum class CommissioningWindowOption |
| { |
| kOriginalSetupCode = 0, |
| kTokenWithRandomPIN, |
| kTokenWithProvidedPIN, |
| }; |
| |
| CHIP_ERROR Init(ControllerInitParams params); |
| |
| /** |
| * @brief |
| * Tears down the entirety of the stack, including destructing key objects in the system. |
| * This expects to be called with external thread synchronization, and will not internally |
| * grab the CHIP stack lock. |
| * |
| * This will also not stop the CHIP event queue / thread (if one exists). Consumers are expected to |
| * ensure this happend before calling this method. |
| */ |
| virtual CHIP_ERROR Shutdown(); |
| |
| CHIP_ERROR GetPeerAddressAndPort(PeerId peerId, Inet::IPAddress & addr, uint16_t & port); |
| |
| /** |
| * This function returns true if the device corresponding to `deviceId` has previously been commissioned |
| * on the fabric. |
| */ |
| bool DoesDevicePairingExist(const PeerId & deviceId); |
| |
| /** |
| * This function finds the device corresponding to deviceId, and establishes a secure connection with it. |
| * Once the connection is successfully establishes (or if it's already connected), it calls `onConnectedDevice` |
| * callback. If it fails to establish the connection, it calls `onError` callback. |
| */ |
| virtual CHIP_ERROR GetConnectedDevice(NodeId deviceId, Callback::Callback<OnDeviceConnected> * onConnection, |
| Callback::Callback<OnDeviceConnectionFailure> * onFailure) |
| { |
| VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); |
| return mCASESessionManager->FindOrEstablishSession(deviceId, onConnection, onFailure); |
| } |
| |
| /** |
| * @brief |
| * This function update the device informations asynchronously using dnssd. |
| * |
| * @param[in] deviceId Node ID for the CHIP device |
| * |
| * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. |
| */ |
| CHIP_ERROR UpdateDevice(NodeId deviceId) |
| { |
| VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); |
| return mCASESessionManager->ResolveDeviceAddress(deviceId); |
| } |
| |
| /** |
| * @brief |
| * Compute a PASE verifier and passcode ID for the desired setup pincode. |
| * |
| * This can be used to open a commissioning window on the device for |
| * additional administrator commissioning. |
| * |
| * @param[in] iterations The number of iterations to use when generating the verifier |
| * @param[in] setupPincode The desired PIN code to use |
| * @param[in] salt The 16-byte salt for verifier computation |
| * @param[out] outVerifier The PASEVerifier to be populated on success |
| * @param[out] outPasscodeId The passcode ID to be populated on success |
| * |
| * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error |
| */ |
| CHIP_ERROR ComputePASEVerifier(uint32_t iterations, uint32_t setupPincode, const ByteSpan & salt, PASEVerifier & outVerifier, |
| uint32_t & outPasscodeId); |
| |
| /** |
| * @brief |
| * Trigger a paired device to re-enter the commissioning mode. The device will exit the commissioning mode |
| * after a successful commissioning, or after the given `timeout` time. |
| * |
| * @param[in] deviceId The device Id. |
| * @param[in] timeout The commissioning mode should terminate after this much time. |
| * @param[in] iteration The PAKE iteration count associated with the PAKE Passcode ID and ephemeral |
| * PAKE passcode verifier to be used for this commissioning. |
| * @param[in] discriminator The long discriminator for the DNS-SD advertisement. |
| * @param[in] option The commissioning window can be opened using the original setup code, or an |
| * onboarding token can be generated using a random setup PIN code (or with |
| * the PIN code provied in the setupPayload). |
| * @param[out] payload The generated setup payload. |
| * - The payload is generated only if the user didn't ask for using the original setup code. |
| * - If the user asked to use the provided setup PIN, the PIN must be provided as part of |
| * this payload |
| * |
| * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error |
| */ |
| CHIP_ERROR OpenCommissioningWindow(NodeId deviceId, uint16_t timeout, uint16_t iteration, uint16_t discriminator, |
| uint8_t option, SetupPayload & payload) |
| { |
| return OpenCommissioningWindowWithCallback(deviceId, timeout, iteration, discriminator, option, nullptr); |
| } |
| |
| /** |
| * @brief |
| * Trigger a paired device to re-enter the commissioning mode. The device will exit the commissioning mode |
| * after a successful commissioning, or after the given `timeout` time. |
| * |
| * @param[in] deviceId The device Id. |
| * @param[in] timeout The commissioning mode should terminate after this much time. |
| * @param[in] iteration The PAKE iteration count associated with the PAKE Passcode ID and ephemeral |
| * PAKE passcode verifier to be used for this commissioning. |
| * @param[in] discriminator The long discriminator for the DNS-SD advertisement. |
| * @param[in] option The commissioning window can be opened using the original setup code, or an |
| * onboarding token can be generated using a random setup PIN code (or with |
| * the PIN code provied in the setupPayload). |
| * @param[in] callback The function to be called on success or failure of opening of commissioning window. |
| * |
| * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error |
| */ |
| CHIP_ERROR OpenCommissioningWindowWithCallback(NodeId deviceId, uint16_t timeout, uint16_t iteration, uint16_t discriminator, |
| uint8_t option, Callback::Callback<OnOpenCommissioningWindow> * callback); |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| void RegisterDeviceAddressUpdateDelegate(DeviceAddressUpdateDelegate * delegate) { mDeviceAddressUpdateDelegate = delegate; } |
| void RegisterDeviceDiscoveryDelegate(DeviceDiscoveryDelegate * delegate) { mDeviceDiscoveryDelegate = delegate; } |
| #endif |
| |
| /** |
| * @brief Get the Compressed Fabric ID assigned to the device. |
| */ |
| uint64_t GetCompressedFabricId() const { return mLocalId.GetCompressedFabricId(); } |
| |
| /** |
| * @brief Get the raw Fabric ID assigned to the device. |
| */ |
| uint64_t GetFabricId() const { return mFabricId; } |
| |
| void ReleaseOperationalDevice(NodeId remoteDeviceId); |
| |
| protected: |
| enum class State |
| { |
| NotInitialized, |
| Initialized |
| }; |
| |
| State mState; |
| |
| CASESessionManager * mCASESessionManager = nullptr; |
| |
| Dnssd::DnssdCache<CHIP_CONFIG_MDNS_CACHE_SIZE> mDNSCache; |
| |
| SerializableU64Set<kNumMaxPairedDevices> mPairedDevices; |
| bool mPairedDevicesInitialized; |
| |
| PeerId mLocalId = PeerId(); |
| FabricId mFabricId = kUndefinedFabricId; |
| |
| PersistentStorageDelegate * mStorageDelegate = nullptr; |
| #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| Transport::PeerAddress ToPeerAddress(const chip::Dnssd::ResolvedNodeData & nodeData) const; |
| |
| DeviceAddressUpdateDelegate * mDeviceAddressUpdateDelegate = nullptr; |
| // TODO(cecille): Make this configuarable. |
| static constexpr int kMaxCommissionableNodes = 10; |
| Dnssd::DiscoveredNodeData mCommissionableNodes[kMaxCommissionableNodes]; |
| #endif |
| DeviceControllerSystemState * mSystemState = nullptr; |
| |
| CHIP_ERROR InitializePairedDeviceList(); |
| CHIP_ERROR SetPairedDeviceList(ByteSpan pairedDeviceSerializedSet); |
| ControllerDeviceInitParams GetControllerDeviceInitParams(); |
| |
| void PersistNextKeyId(); |
| |
| FabricIndex mFabricIndex = kMinValidFabricIndex; |
| |
| OperationalCredentialsDelegate * mOperationalCredentialsDelegate; |
| |
| SessionIDAllocator mIDAllocator; |
| |
| uint16_t mVendorId; |
| |
| //////////// SessionReleaseDelegate Implementation /////////////// |
| void OnSessionReleased(SessionHandle session) override; |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| //////////// ResolverDelegate Implementation /////////////// |
| void OnNodeIdResolved(const chip::Dnssd::ResolvedNodeData & nodeData) override; |
| void OnNodeIdResolutionFailed(const chip::PeerId & peerId, CHIP_ERROR error) override; |
| DiscoveredNodeList GetDiscoveredNodes() override { return DiscoveredNodeList(mCommissionableNodes); } |
| #endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| |
| private: |
| void ReleaseOperationalDevice(OperationalDeviceProxy * device); |
| |
| Callback::Callback<DefaultSuccessCallback> mOpenPairingSuccessCallback; |
| Callback::Callback<DefaultFailureCallback> mOpenPairingFailureCallback; |
| |
| // TODO - Support opening commissioning window simultaneously on multiple devices |
| Callback::Callback<OnOpenCommissioningWindow> * mCommissioningWindowCallback = nullptr; |
| SetupPayload mSetupPayload; |
| NodeId mDeviceWithCommissioningWindowOpen; |
| |
| static void OnOpenPairingWindowSuccessResponse(void * context); |
| static void OnOpenPairingWindowFailureResponse(void * context, uint8_t status); |
| |
| CHIP_ERROR ProcessControllerNOCChain(const ControllerInitParams & params); |
| uint16_t mPAKEVerifierID = 1; |
| }; |
| |
| /** |
| * @brief |
| * The commissioner applications can use this class to pair new/unpaired CHIP devices. The application is |
| * required to provide write access to the persistent storage, where the paired device information |
| * will be stored. |
| */ |
| class DLL_EXPORT DeviceCommissioner : public DeviceController, |
| public SessionCreationDelegate, |
| #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable |
| public Protocols::UserDirectedCommissioning::InstanceNameResolver, |
| public Protocols::UserDirectedCommissioning::UserConfirmationProvider, |
| #endif |
| public SessionEstablishmentDelegate |
| { |
| public: |
| DeviceCommissioner(); |
| ~DeviceCommissioner() {} |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable |
| /** |
| * Set port for User Directed Commissioning |
| */ |
| CHIP_ERROR SetUdcListenPort(uint16_t listenPort); |
| #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY |
| |
| /** |
| * Commissioner-specific initialization, includes parameters such as the pairing delegate. |
| */ |
| CHIP_ERROR Init(CommissionerInitParams params); |
| |
| /** |
| * @brief |
| * Tears down the entirety of the stack, including destructing key objects in the system. |
| * This is not a thread-safe API, and should be called with external synchronization. |
| * |
| * Please see implementation for more details. |
| */ |
| CHIP_ERROR Shutdown() override; |
| |
| // ----- Connection Management ----- |
| /** |
| * @brief |
| * Pair a CHIP device with the provided code. The code can be either a QRCode |
| * or a Manual Setup Code. |
| * Use registered DevicePairingDelegate object to receive notifications on |
| * pairing status updates. |
| * |
| * Note: Pairing process requires that the caller has registered PersistentStorageDelegate |
| * in the Init() call. |
| * |
| * @param[in] remoteDeviceId The remote device Id. |
| * @param[in] setUpCode The setup code for connecting to the device |
| */ |
| CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode); |
| |
| /** |
| * @brief |
| * Pair a CHIP device with the provided Rendezvous connection parameters. |
| * Use registered DevicePairingDelegate object to receive notifications on |
| * pairing status updates. |
| * |
| * Note: Pairing process requires that the caller has registered PersistentStorageDelegate |
| * in the Init() call. |
| * |
| * @param[in] remoteDeviceId The remote device Id. |
| * @param[in] params The Rendezvous connection parameters |
| */ |
| CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & params); |
| |
| CHIP_ERROR GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** device); |
| |
| CHIP_ERROR GetConnectedDevice(NodeId deviceId, Callback::Callback<OnDeviceConnected> * onConnection, |
| Callback::Callback<OnDeviceConnectionFailure> * onFailure) override; |
| |
| /** |
| * @brief |
| * This function stops a pairing process that's in progress. It does not delete the pairing of a previously |
| * paired device. |
| * |
| * @param[in] remoteDeviceId The remote device Id. |
| * |
| * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error |
| */ |
| CHIP_ERROR StopPairing(NodeId remoteDeviceId); |
| |
| /** |
| * @brief |
| * Remove pairing for a paired device. If the device is currently being paired, it'll stop the pairing process. |
| * |
| * @param[in] remoteDeviceId The remote device Id. |
| * |
| * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error |
| */ |
| CHIP_ERROR UnpairDevice(NodeId remoteDeviceId); |
| |
| //////////// SessionEstablishmentDelegate Implementation /////////////// |
| void OnSessionEstablishmentError(CHIP_ERROR error) override; |
| void OnSessionEstablished() override; |
| |
| void RendezvousCleanup(CHIP_ERROR status); |
| |
| void AdvanceCommissioningStage(CHIP_ERROR err); |
| |
| #if CONFIG_NETWORK_LAYER_BLE |
| /** |
| * @brief |
| * Once we have finished all commissioning work, the Controller should close the BLE |
| * connection to the device and establish CASE session / another PASE session to the device |
| * if needed. |
| * @return CHIP_ERROR The return status |
| */ |
| CHIP_ERROR CloseBleConnection(); |
| #endif |
| #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD |
| /** |
| * @brief |
| * Discover all devices advertising as commissionable. |
| * Should be called on main loop thread. |
| * * @param[in] filter Browse filter - controller will look for only the specified subtype. |
| * @return CHIP_ERROR The return status |
| */ |
| CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter); |
| |
| /** |
| * @brief |
| * Returns information about discovered devices. |
| * Should be called on main loop thread. |
| * @return const DiscoveredNodeData* info about the selected device. May be nullptr if no information has been returned yet. |
| */ |
| const Dnssd::DiscoveredNodeData * GetDiscoveredDevice(int idx); |
| |
| /** |
| * @brief |
| * Returns the max number of commissionable nodes this commissioner can track mdns information for. |
| * @return int The max number of commissionable nodes supported |
| */ |
| int GetMaxCommissionableNodesSupported() { return kMaxCommissionableNodes; } |
| |
| void OnNodeIdResolved(const chip::Dnssd::ResolvedNodeData & nodeData) override; |
| void OnNodeIdResolutionFailed(const chip::PeerId & peerId, CHIP_ERROR error) override; |
| #endif |
| #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable |
| /** |
| * @brief |
| * Called when a UDC message is received specifying the given instanceName |
| * This method indicates that UDC Server needs the Commissionable Node corresponding to |
| * the given instance name to be found. UDC Server will wait for OnCommissionableNodeFound. |
| * |
| * @param instanceName DNS-SD instance name for the client requesting commissioning |
| * |
| */ |
| void FindCommissionableNode(char * instanceName) override; |
| |
| /** |
| * @brief |
| * Called when a UDC message has been received and corresponding nodeData has been found. |
| * It is expected that the implementer will prompt the user to confirm their intention to |
| * commission the given node, and provide the setup code to allow commissioning to proceed. |
| * |
| * @param nodeData DNS-SD node information for the client requesting commissioning |
| * |
| */ |
| void OnUserDirectedCommissioningRequest(UDCClientState state) override; |
| |
| /** |
| * @brief |
| * Overrides method from AbstractDnssdDiscoveryController |
| * |
| * @param nodeData DNS-SD node information |
| * |
| */ |
| void OnNodeDiscoveryComplete(const chip::Dnssd::DiscoveredNodeData & nodeData) override; |
| |
| /** |
| * @brief |
| * Return the UDC Server instance |
| * |
| */ |
| UserDirectedCommissioningServer * GetUserDirectedCommissioningServer() { return mUdcServer; } |
| #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY |
| |
| void RegisterPairingDelegate(DevicePairingDelegate * pairingDelegate) { mPairingDelegate = pairingDelegate; } |
| |
| private: |
| DevicePairingDelegate * mPairingDelegate; |
| |
| CommissioneeDeviceProxy * mDeviceBeingCommissioned = nullptr; |
| DeviceProxy * mDeviceOperational = nullptr; |
| |
| Credentials::CertificateType mCertificateTypeBeingRequested = Credentials::CertificateType::kUnknown; |
| |
| /* TODO: BLE rendezvous and IP rendezvous should share the same procedure, so this is just a |
| workaround-like flag and should be removed in the future. |
| When using IP rendezvous, we need to disable network provisioning. In the future, network |
| provisioning will no longer be a part of rendezvous procedure. */ |
| bool mIsIPRendezvous; |
| |
| /* This field is true when device pairing information changes, e.g. a new device is paired, or |
| the pairing for a device is removed. The DeviceCommissioner uses this to decide when to |
| persist the device list */ |
| bool mPairedDevicesUpdated; |
| |
| CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing; |
| |
| BitMapObjectPool<CommissioneeDeviceProxy, kNumMaxActiveDevices> mCommissioneeDevicePool; |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable |
| UserDirectedCommissioningServer * mUdcServer = nullptr; |
| // mUdcTransportMgr is for insecure communication (ex. user directed commissioning) |
| DeviceIPTransportMgr * mUdcTransportMgr = nullptr; |
| uint16_t mUdcListenPort = CHIP_UDC_PORT; |
| #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY |
| |
| void FreeRendezvousSession(); |
| |
| CHIP_ERROR LoadKeyId(PersistentStorageDelegate * delegate, uint16_t & out); |
| |
| void OnSessionEstablishmentTimeout(); |
| |
| //////////// SessionCreationDelegate Implementation /////////////// |
| void OnNewSession(SessionHandle session) override; |
| //////////// SessionReleaseDelegate Implementation /////////////// |
| void OnSessionReleased(SessionHandle session) override; |
| |
| static void OnSessionEstablishmentTimeoutCallback(System::Layer * aLayer, void * aAppState); |
| |
| /* This function sends a Device Attestation Certificate chain request to the device. |
| The function does not hold a reference to the device object. |
| */ |
| CHIP_ERROR SendCertificateChainRequestCommand(CommissioneeDeviceProxy * device, Credentials::CertificateType certificateType); |
| /* This function sends an Attestation request to the device. |
| The function does not hold a reference to the device object. |
| */ |
| CHIP_ERROR SendAttestationRequestCommand(CommissioneeDeviceProxy * device, const ByteSpan & attestationNonce); |
| /* This function sends an OpCSR request to the device. |
| The function does not hold a refernce to the device object. |
| */ |
| CHIP_ERROR SendOperationalCertificateSigningRequestCommand(CommissioneeDeviceProxy * device); |
| /* This function sends the operational credentials to the device. |
| The function does not hold a refernce to the device object. |
| */ |
| CHIP_ERROR SendOperationalCertificate(CommissioneeDeviceProxy * device, const ByteSpan & nocCertBuf, |
| const ByteSpan & icaCertBuf); |
| /* This function sends the trusted root certificate to the device. |
| The function does not hold a refernce to the device object. |
| */ |
| CHIP_ERROR SendTrustedRootCertificate(CommissioneeDeviceProxy * device, const ByteSpan & rcac); |
| |
| /* This function is called by the commissioner code when the device completes |
| the operational credential provisioning process. |
| The function does not hold a refernce to the device object. |
| */ |
| CHIP_ERROR OnOperationalCredentialsProvisioningCompletion(CommissioneeDeviceProxy * device); |
| |
| /* Callback when the previously sent CSR request results in failure */ |
| static void OnCSRFailureResponse(void * context, uint8_t status); |
| |
| static void OnCertificateChainFailureResponse(void * context, uint8_t status); |
| static void OnCertificateChainResponse(void * context, ByteSpan certificate); |
| |
| static void OnAttestationFailureResponse(void * context, uint8_t status); |
| static void OnAttestationResponse(void * context, chip::ByteSpan attestationElements, chip::ByteSpan signature); |
| |
| /** |
| * @brief |
| * This function is called by the IM layer when the commissioner receives the CSR from the device. |
| * (Reference: Specifications section 11.22.5.8. OpCSR Elements) |
| * |
| * @param[in] context The context provided while registering the callback. |
| * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements. |
| * @param[in] AttestationSignature Cryptographic signature generated for the fields in the response message. |
| */ |
| static void OnOperationalCertificateSigningRequest(void * context, ByteSpan NOCSRElements, ByteSpan AttestationSignature); |
| |
| /* Callback when adding operational certs to device results in failure */ |
| static void OnAddNOCFailureResponse(void * context, uint8_t status); |
| /* Callback when the device confirms that it has added the operational certificates */ |
| static void OnOperationalCertificateAddResponse(void * context, uint8_t StatusCode, uint8_t FabricIndex, CharSpan DebugText); |
| |
| /* Callback when the device confirms that it has added the root certificate */ |
| static void OnRootCertSuccessResponse(void * context); |
| /* Callback called when adding root cert to device results in failure */ |
| static void OnRootCertFailureResponse(void * context, uint8_t status); |
| |
| static void OnDeviceConnectedFn(void * context, DeviceProxy * device); |
| static void OnDeviceConnectionFailureFn(void * context, NodeId deviceId, CHIP_ERROR error); |
| |
| static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac, |
| const ByteSpan & rcac); |
| |
| /** |
| * @brief |
| * This function processes the CSR sent by the device. |
| * (Reference: Specifications section 11.22.5.8. OpCSR Elements) |
| * |
| * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements. |
| * @param[in] AttestationSignature Cryptographic signature generated for all the above fields. |
| */ |
| CHIP_ERROR ProcessOpCSR(const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature); |
| |
| /** |
| * @brief |
| * This function processes the DAC or PAI certificate sent by the device. |
| */ |
| CHIP_ERROR ProcessCertificateChain(const ByteSpan & certificate); |
| |
| /** |
| * @brief |
| * This function validates the Attestation Information sent by the device. |
| * |
| * @param[in] attestationElements Attestation Elements TLV. |
| * @param[in] signature Attestation signature generated for all the above fields + Attestation Challenge. |
| */ |
| CHIP_ERROR ValidateAttestationInfo(const ByteSpan & attestationElements, const ByteSpan & signature); |
| |
| void HandleAttestationResult(CHIP_ERROR err); |
| |
| CommissioneeDeviceProxy * FindCommissioneeDevice(SessionHandle session); |
| CommissioneeDeviceProxy * FindCommissioneeDevice(NodeId id); |
| void ReleaseCommissioneeDevice(CommissioneeDeviceProxy * device); |
| |
| // Cluster callbacks for advancing commissioning flows |
| Callback::Callback<BasicSuccessCallback> mSuccess; |
| Callback::Callback<BasicFailureCallback> mFailure; |
| |
| CommissioningStage GetNextCommissioningStage(); |
| static CHIP_ERROR ConvertFromNodeOperationalCertStatus(uint8_t err); |
| |
| Callback::Callback<OperationalCredentialsClusterCertificateChainResponseCallback> mCertificateChainResponseCallback; |
| Callback::Callback<OperationalCredentialsClusterAttestationResponseCallback> mAttestationResponseCallback; |
| Callback::Callback<OperationalCredentialsClusterOpCSRResponseCallback> mOpCSRResponseCallback; |
| Callback::Callback<OperationalCredentialsClusterNOCResponseCallback> mNOCResponseCallback; |
| Callback::Callback<DefaultSuccessCallback> mRootCertResponseCallback; |
| Callback::Callback<DefaultFailureCallback> mOnCertificateChainFailureCallback; |
| Callback::Callback<DefaultFailureCallback> mOnAttestationFailureCallback; |
| Callback::Callback<DefaultFailureCallback> mOnCSRFailureCallback; |
| Callback::Callback<DefaultFailureCallback> mOnCertFailureCallback; |
| Callback::Callback<DefaultFailureCallback> mOnRootCertFailureCallback; |
| |
| Callback::Callback<OnDeviceConnected> mOnDeviceConnectedCallback; |
| Callback::Callback<OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback; |
| |
| Callback::Callback<OnNOCChainGeneration> mDeviceNOCChainCallback; |
| SetUpCodePairer mSetUpCodePairer; |
| }; |
| |
| } // namespace Controller |
| } // namespace chip |