From 2130956e1dbcf25c7c909725f1609c4cf217cb6f Mon Sep 17 00:00:00 2001 From: C Freeman Date: Fri, 3 Dec 2021 11:45:30 -0500 Subject: [PATCH] Separate PASE and commissioning. (#12060) * Separate PASE and commissioning. Current "PairDevice" commands will continue to work as previously, but separating out the commissioning part from the PASE connection so vendors can have an easier time implemeting their own commissioning flows. * Update src/controller/CHIPDeviceController.cpp Co-authored-by: Martin Turon * Fix android. * Restyled by autopep8 * Add comments on appropriate use of functions. Co-authored-by: Martin Turon Co-authored-by: Restyled.io --- src/controller/CHIPDeviceController.cpp | 121 ++++++++++++------ src/controller/CHIPDeviceController.h | 43 ++++++- .../java/CHIPDeviceController-JNI.cpp | 26 ++-- .../ChipDeviceController-ScriptBinding.cpp | 21 +++ src/controller/python/chip-device-ctrl.py | 54 ++++++++ src/controller/python/chip/ChipDeviceCtrl.py | 31 +++++ .../secure_channel/RendezvousParameters.h | 47 ++++--- 7 files changed, 273 insertions(+), 70 deletions(-) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 1157992b489109..6d4857e02ba217 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -761,6 +761,20 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, const char * se CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParameters & params) { + CommissioningParameters commissioningParams; + return PairDevice(remoteDeviceId, params, commissioningParams); +} + +CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams, + CommissioningParameters & commissioningParams) +{ + ReturnErrorOnFailure(EstablishPASEConnection(remoteDeviceId, rendezvousParams)); + return Commission(remoteDeviceId, commissioningParams); +} + +CHIP_ERROR DeviceCommissioner::EstablishPASEConnection(NodeId remoteDeviceId, RendezvousParameters & params) +{ + CHIP_ERROR err = CHIP_NO_ERROR; CommissioneeDeviceProxy * device = nullptr; Transport::PeerAddress peerAddress = Transport::PeerAddress::UDP(Inet::IPAddress::Any); @@ -804,30 +818,6 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam mDeviceBeingCommissioned = device; - // If the CSRNonce is passed in, using that else using a random one.. - if (params.HasCSRNonce()) - { - ReturnErrorOnFailure(device->SetCSRNonce(params.GetCSRNonce().Value())); - } - else - { - uint8_t mCSRNonce[kOpCSRNonceLength]; - Crypto::DRBG_get_bytes(mCSRNonce, sizeof(mCSRNonce)); - ReturnErrorOnFailure(device->SetCSRNonce(ByteSpan(mCSRNonce))); - } - - // If the AttestationNonce is passed in, using that else using a random one.. - if (params.HasAttestationNonce()) - { - ReturnErrorOnFailure(device->SetAttestationNonce(params.GetAttestationNonce().Value())); - } - else - { - uint8_t mAttestationNonce[kAttestationNonceLength]; - Crypto::DRBG_get_bytes(mAttestationNonce, sizeof(mAttestationNonce)); - ReturnErrorOnFailure(device->SetAttestationNonce(ByteSpan(mAttestationNonce))); - } - mIsIPRendezvous = (params.GetPeerAddress().GetTransportType() != Transport::Type::kBle); device->Init(GetControllerDeviceInitParams(), remoteDeviceId, peerAddress, fabric->GetFabricIndex()); @@ -835,8 +825,6 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam err = device->GetPairing().MessageDispatch().Init(mSystemState->SessionMgr()); SuccessOrExit(err); - mSystemState->SystemLayer()->StartTimer(chip::System::Clock::Milliseconds32(kSessionEstablishmentTimeout), - OnSessionEstablishmentTimeoutCallback, this); if (params.GetPeerAddress().GetTransportType() != Transport::Type::kBle) { device->SetAddress(params.GetPeerAddress().GetIPAddress()); @@ -874,9 +862,10 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam err = device->GetPairing().Pair(params.GetPeerAddress(), params.GetSetupPINCode(), keyID, exchangeCtxt, this); SuccessOrExit(err); - // Immediately persist the updted mNextKeyID value + // Immediately persist the updated mNextKeyID value // TODO maybe remove FreeRendezvousSession() since mNextKeyID is always persisted immediately PersistNextKeyId(); + mCommissioningStage = kSecurePairing; exit: if (err != CHIP_NO_ERROR) @@ -897,6 +886,58 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam return err; } +CHIP_ERROR DeviceCommissioner::Commission(NodeId remoteDeviceId, CommissioningParameters & params) +{ + // TODO(cecille): Can we get rid of mDeviceBeingCommissioned and use the remote id instead? Would require storing the + // commissioning stage in the device. + CommissioneeDeviceProxy * device = mDeviceBeingCommissioned; + if (device->GetDeviceId() != remoteDeviceId || (!device->IsSecureConnected() && !device->IsSessionSetupInProgress())) + { + ChipLogError(Controller, "Invalid device for commissioning" ChipLogFormatX64, ChipLogValueX64(remoteDeviceId)); + return CHIP_ERROR_INCORRECT_STATE; + } + if (mCommissioningStage != CommissioningStage::kSecurePairing) + { + ChipLogError(Controller, "Commissioning already in progress - not restarting"); + return CHIP_ERROR_INCORRECT_STATE; + } + // If the CSRNonce is passed in, using that else using a random one.. + if (params.HasCSRNonce()) + { + ReturnErrorOnFailure(device->SetCSRNonce(params.GetCSRNonce().Value())); + } + else + { + uint8_t mCSRNonce[kOpCSRNonceLength]; + Crypto::DRBG_get_bytes(mCSRNonce, sizeof(mCSRNonce)); + ReturnErrorOnFailure(device->SetCSRNonce(ByteSpan(mCSRNonce))); + } + + // If the AttestationNonce is passed in, using that else using a random one.. + if (params.HasAttestationNonce()) + { + ReturnErrorOnFailure(device->SetAttestationNonce(params.GetAttestationNonce().Value())); + } + else + { + uint8_t mAttestationNonce[kAttestationNonceLength]; + Crypto::DRBG_get_bytes(mAttestationNonce, sizeof(mAttestationNonce)); + ReturnErrorOnFailure(device->SetAttestationNonce(ByteSpan(mAttestationNonce))); + } + + mSystemState->SystemLayer()->StartTimer(chip::System::Clock::Milliseconds32(kSessionEstablishmentTimeout), + OnSessionEstablishmentTimeoutCallback, this); + if (device->IsSecureConnected()) + { + AdvanceCommissioningStage(CHIP_NO_ERROR); + } + else + { + mRunCommissioningAfterConnection = true; + } + return CHIP_NO_ERROR; +} + CHIP_ERROR DeviceCommissioner::StopPairing(NodeId remoteDeviceId) { VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); @@ -981,21 +1022,29 @@ void DeviceCommissioner::OnSessionEstablished() // TODO: Add code to receive OpCSR from the device, and process the signing request // For IP rendezvous, this is sent as part of the state machine. - bool usingLegacyFlowWithImmediateStart = !mIsIPRendezvous; - - if (usingLegacyFlowWithImmediateStart) + if (mRunCommissioningAfterConnection) { - err = SendCertificateChainRequestCommand(mDeviceBeingCommissioned, CertificateType::kPAI); - if (err != CHIP_NO_ERROR) + mRunCommissioningAfterConnection = false; + bool usingLegacyFlowWithImmediateStart = !mIsIPRendezvous; + if (usingLegacyFlowWithImmediateStart) { - ChipLogError(Ble, "Failed in sending 'Certificate Chain request' command to the device: err %s", ErrorStr(err)); - OnSessionEstablishmentError(err); - return; + err = SendCertificateChainRequestCommand(mDeviceBeingCommissioned, CertificateType::kPAI); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Ble, "Failed in sending 'Certificate Chain request' command to the device: err %s", ErrorStr(err)); + OnSessionEstablishmentError(err); + return; + } + } + else + { + AdvanceCommissioningStage(CHIP_NO_ERROR); } } else { - AdvanceCommissioningStage(CHIP_NO_ERROR); + ChipLogProgress(Controller, "OnPairingComplete"); + mPairingDelegate->OnPairingComplete(CHIP_NO_ERROR); } } diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 32606dc11a4dcd..998bfd9b5ffa75 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -490,9 +491,46 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, * in the Init() call. * * @param[in] remoteDeviceId The remote device Id. - * @param[in] params The Rendezvous connection parameters + * @param[in] rendezvousParams The Rendezvous connection parameters + * @param[in] commssioningParams The commissioning parameters (uses defualt if not supplied) */ - CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & params); + CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams); + CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams, + CommissioningParameters & commissioningParams); + + /** + * @brief + * Start establishing a PASE connection with a node for the purposes of commissioning. + * Commissioners that wish to use the auto-commissioning functions should use the + * supplied "PairDevice" functions above to automatically establish a connection then + * perform commissioning. This function is intended to be use by commissioners that + * are not using the supplied auto-commissioner. + * + * This function is non-blocking. PASE is established once the DevicePairingDelegate + * receives the OnPairingComplete call. + * + * PASE connections can only be established with nodes that have their commissioning + * window open. The PASE connection will fail if this window is not open and the + * OnPairingComplete will be called with an error. + * + * @param[in] remoteDeviceId The remote device Id. + * @param[in] rendezvousParams The Rendezvous connection parameters + */ + CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, RendezvousParameters & params); + + /** + * @brief + * Start the auto-commissioning process on a node after establishing a PASE connection. + * This function is intended to be used in conjunction with the EstablishPASEConnection + * function. It can be called either before or after the DevicePairingDelegate receives + * the OnPairingComplete call. Commissioners that want to perform simple auto-commissioning + * should use the supplied "PairDevice" functions above, which will establish the PASE + * connection and commission automatically. + * + * @param[in] remoteDeviceId The remote device Id. + * @param[in] params The commissioning parameters + */ + CHIP_ERROR Commission(NodeId remoteDeviceId, CommissioningParameters & params); CHIP_ERROR GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** device); @@ -628,6 +666,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, bool mPairedDevicesUpdated; CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing; + bool mRunCommissioningAfterConnection = false; BitMapObjectPool mCommissioneeDevicePool; diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 2c5a8d7af593c4..5364aceebd9698 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -185,18 +185,19 @@ JNI_METHOD(void, pairDevice) ChipLogProgress(Controller, "pairDevice() called with device ID, connection object, and pincode"); - RendezvousParameters params = RendezvousParameters() - .SetSetupPINCode(pinCode) + RendezvousParameters rendezvousParams = RendezvousParameters() + .SetSetupPINCode(pinCode) #if CONFIG_NETWORK_LAYER_BLE - .SetConnectionObject(reinterpret_cast(connObj)) + .SetConnectionObject(reinterpret_cast(connObj)) #endif - .SetPeerAddress(Transport::PeerAddress::BLE()); + .SetPeerAddress(Transport::PeerAddress::BLE()); + CommissioningParameters commissioningParams = CommissioningParameters(); if (csrNonce != nullptr) { JniByteArray jniCsrNonce(env, csrNonce); - params.SetCSRNonce(jniCsrNonce.byteSpan()); + commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan()); } - err = wrapper->Controller()->PairDevice(deviceId, params); + err = wrapper->Controller()->PairDevice(deviceId, rendezvousParams, commissioningParams); if (err != CHIP_NO_ERROR) { @@ -221,16 +222,17 @@ JNI_METHOD(void, pairDeviceWithAddress) ChipLogError(Controller, "Failed to parse IP address."), JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, CHIP_ERROR_INVALID_ARGUMENT)); - RendezvousParameters params = RendezvousParameters() - .SetDiscriminator(discriminator) - .SetSetupPINCode(pinCode) - .SetPeerAddress(Transport::PeerAddress::UDP(addr, port)); + RendezvousParameters rendezvousParams = RendezvousParameters() + .SetDiscriminator(discriminator) + .SetSetupPINCode(pinCode) + .SetPeerAddress(Transport::PeerAddress::UDP(addr, port)); + CommissioningParameters commissioningParams = CommissioningParameters(); if (csrNonce != nullptr) { JniByteArray jniCsrNonce(env, csrNonce); - params.SetCSRNonce(jniCsrNonce.byteSpan()); + commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan()); } - err = wrapper->Controller()->PairDevice(deviceId, params); + err = wrapper->Controller()->PairDevice(deviceId, rendezvousParams, commissioningParams); if (err != CHIP_NO_ERROR) { diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index 789e5855d92289..c16ea817b4c092 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -112,6 +112,10 @@ ChipError::StorageType pychip_DeviceController_ConnectBLE(chip::Controller::Devi ChipError::StorageType pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr, uint32_t setupPINCode, chip::NodeId nodeid); ChipError::StorageType pychip_DeviceController_CloseSession(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid); +ChipError::StorageType pychip_DeviceController_EstablishPASESessionIP(chip::Controller::DeviceCommissioner * devCtrl, + const char * peerAddrStr, uint32_t setupPINCode, + chip::NodeId nodeid); +ChipError::StorageType pychip_DeviceController_Commission(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid); ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesLongDiscriminator(chip::Controller::DeviceCommissioner * devCtrl, @@ -346,6 +350,23 @@ ChipError::StorageType pychip_DeviceController_CloseSession(chip::Controller::De { return pychip_GetConnectedDeviceByNodeId(devCtrl, nodeid, CloseSessionCallback); } +ChipError::StorageType pychip_DeviceController_EstablishPASESessionIP(chip::Controller::DeviceCommissioner * devCtrl, + const char * peerAddrStr, uint32_t setupPINCode, + chip::NodeId nodeid) +{ + chip::Inet::IPAddress peerAddr; + chip::Transport::PeerAddress addr; + RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode); + VerifyOrReturnError(chip::Inet::IPAddress::FromString(peerAddrStr, peerAddr), CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + addr.SetTransportType(chip::Transport::Type::kUdp).SetIPAddress(peerAddr); + params.SetPeerAddress(addr).SetDiscriminator(0); + return devCtrl->EstablishPASEConnection(nodeid, params).AsInteger(); +} +ChipError::StorageType pychip_DeviceController_Commission(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid) +{ + CommissioningParameters params; + return devCtrl->Commission(nodeid, params).AsInteger(); +} ChipError::StorageType pychip_DeviceController_DiscoverAllCommissionableNodes(chip::Controller::DeviceCommissioner * devCtrl) { diff --git a/src/controller/python/chip-device-ctrl.py b/src/controller/python/chip-device-ctrl.py index 03b31548d1c2e0..54bfef54b96b42 100755 --- a/src/controller/python/chip-device-ctrl.py +++ b/src/controller/python/chip-device-ctrl.py @@ -200,6 +200,8 @@ def __init__(self, rendezvousAddr=None, controllerNodeId=0, bluetoothAdapter=Non "close-ble", "close-session", "resolve", + "paseonly", + "commission", "zcl", "zclread", "zclsubscribe", @@ -491,6 +493,58 @@ def ConnectFromSetupPayload(self, setupPayload, nodeid): print(f"Unable to connect: {ex}") return -1 + def do_paseonly(self, line): + """ + paseonly -ip [] + + TODO: Add more methods to connect to device (like cert for auth, and IP + for connection) + """ + + try: + args = shlex.split(line) + if len(args) <= 1: + print("Usage:") + self.do_help("paseonly") + return + + nodeid = random.randint(1, 1000000) # Just a random number + if len(args) == 4: + nodeid = int(args[3]) + print("Device is assigned with nodeid = {}".format(nodeid)) + + if args[0] == "-ip" and len(args) >= 3: + self.devCtrl.EstablishPASESessionIP(args[1].encode( + "utf-8"), int(args[2]), nodeid) + else: + print("Usage:") + self.do_help("paseonly") + return + print( + "Device temporary node id (**this does not match spec**): {}".format(nodeid)) + except Exception as ex: + print(str(ex)) + return + + def do_commission(self, line): + """ + commission nodeid + + Runs commissioning on a device that has been connected with paseonly + """ + try: + args = shlex.split(line) + if len(args) != 1: + print("Usage:") + self.do_help("commission") + return + + nodeid = int(args[0]) + self.devCtrl.Commission(nodeid) + except Exception as ex: + print(str(ex)) + return + def do_connect(self, line): """ connect -ip [] diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index a993c2e2d4760e..b0fed9d9a99f04 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -199,6 +199,26 @@ def CloseSession(self, nodeid): self.devCtrl, nodeid) ) + def EstablishPASESessionIP(self, ipaddr, setupPinCode, nodeid): + self.state = DCState.RENDEZVOUS_ONGOING + return self._ChipStack.CallAsync( + lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionIP( + self.devCtrl, ipaddr, setupPinCode, nodeid) + ) + + def Commission(self, nodeid): + self._ChipStack.CallAsync( + lambda: self._dmLib.pychip_DeviceController_Commission( + self.devCtrl, nodeid) + ) + # Wait up to 5 additional seconds for the commissioning complete event + if not self._ChipStack.commissioningCompleteEvent.isSet(): + self._ChipStack.commissioningCompleteEvent.wait(5.0) + if not self._ChipStack.commissioningCompleteEvent.isSet(): + # Error 50 is a timeout + return False + return self._ChipStack.commissioningEventRes == 0 + def ConnectIP(self, ipaddr, setupPinCode, nodeid): # IP connection will run through full commissioning, so we need to wait # for the commissioning complete event, not just any callback. @@ -653,6 +673,11 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_ConnectIP.argtypes = [ c_void_p, c_char_p, c_uint32, c_uint64] + + self._dmLib.pychip_DeviceController_Commission.argtypes = [ + c_void_p, c_uint64] + self._dmLib.pychip_DeviceController_Commission.restype = c_uint32 + self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes.argtypes = [ c_void_p] self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes.restype = c_uint32 @@ -677,6 +702,12 @@ def _InitLib(self): c_void_p] self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled.restype = c_uint32 + self._dmLib.pychip_DeviceController_EstablishPASESessionIP.argtypes = [ + c_void_p, c_char_p, c_uint32, c_uint64] + self._dmLib.pychip_DeviceController_EstablishPASESessionIP.restype = c_uint32 + + self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes.argtypes = [ + c_void_p] self._dmLib.pychip_DeviceController_PrintDiscoveredDevices.argtypes = [ c_void_p] diff --git a/src/protocols/secure_channel/RendezvousParameters.h b/src/protocols/secure_channel/RendezvousParameters.h index 295daff2644ff5..043ad223626059 100644 --- a/src/protocols/secure_channel/RendezvousParameters.h +++ b/src/protocols/secure_channel/RendezvousParameters.h @@ -48,28 +48,12 @@ class RendezvousParameters bool HasPeerAddress() const { return mPeerAddress.IsInitialized(); } Transport::PeerAddress GetPeerAddress() const { return mPeerAddress; } - const Optional GetCSRNonce() const { return mCSRNonce; } - const Optional GetAttestationNonce() const { return mAttestationNonce; } RendezvousParameters & SetPeerAddress(const Transport::PeerAddress & peerAddress) { mPeerAddress = peerAddress; return *this; } - // The lifetime of the buffer csrNonce is pointing to, should exceed the lifetime of RendezvousParameter object. - RendezvousParameters & SetCSRNonce(ByteSpan csrNonce) - { - mCSRNonce.SetValue(csrNonce); - return *this; - } - - // The lifetime of the buffer attestationNonce is pointing to, should exceed the lifetime of RendezvousParameter object. - RendezvousParameters & SetAttestationNonce(ByteSpan attestationNonce) - { - mAttestationNonce.SetValue(attestationNonce); - return *this; - } - bool HasDiscriminator() const { return mDiscriminator <= kMaxRendezvousDiscriminatorValue; } uint16_t GetDiscriminator() const { return mDiscriminator; } RendezvousParameters & SetDiscriminator(uint16_t discriminator) @@ -79,8 +63,6 @@ class RendezvousParameters } bool HasPASEVerifier() const { return mHasPASEVerifier; } - bool HasCSRNonce() const { return mCSRNonce.HasValue(); } - bool HasAttestationNonce() const { return mAttestationNonce.HasValue(); } const PASEVerifier & GetPASEVerifier() const { return mPASEVerifier; } RendezvousParameters & SetPASEVerifier(PASEVerifier & verifier) { @@ -113,8 +95,6 @@ class RendezvousParameters Transport::PeerAddress mPeerAddress; ///< the peer node address uint32_t mSetupPINCode = 0; ///< the target peripheral setup PIN Code uint16_t mDiscriminator = UINT16_MAX; ///< the target peripheral discriminator - Optional mCSRNonce; ///< CSR Nonce passed by the commissioner - Optional mAttestationNonce; ///< Attestation Nonce passed by the commissioner PASEVerifier mPASEVerifier; bool mHasPASEVerifier = false; @@ -125,4 +105,31 @@ class RendezvousParameters #endif // CONFIG_NETWORK_LAYER_BLE }; +class CommissioningParameters +{ +public: + bool HasCSRNonce() const { return mCSRNonce.HasValue(); } + bool HasAttestationNonce() const { return mAttestationNonce.HasValue(); } + const Optional GetCSRNonce() const { return mCSRNonce; } + const Optional GetAttestationNonce() const { return mAttestationNonce; } + + // The lifetime of the buffer csrNonce is pointing to, should exceed the lifetime of CommissioningParameters object. + CommissioningParameters & SetCSRNonce(ByteSpan csrNonce) + { + mCSRNonce.SetValue(csrNonce); + return *this; + } + + // The lifetime of the buffer attestationNonce is pointing to, should exceed the lifetime of CommissioningParameters object. + CommissioningParameters & SetAttestationNonce(ByteSpan attestationNonce) + { + mAttestationNonce.SetValue(attestationNonce); + return *this; + } + +private: + Optional mCSRNonce; ///< CSR Nonce passed by the commissioner + Optional mAttestationNonce; ///< Attestation Nonce passed by the commissioner +}; + } // namespace chip