From 102095109c7aa73780bea24dcc75820868ae5e09 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Sat, 29 Jan 2022 08:31:44 +0100 Subject: [PATCH] =?UTF-8?q?[Controller]=20Update=20CHIPController=20to=20u?= =?UTF-8?q?se=20the=20Invoke=20API=20instead=20of=20r=E2=80=A6=20(#13371)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Convert OpenPairingWindow * Convert CertificateChainRequest * Convert AttestationRequest * Convert OpCSRRequest * Convert AddNOC * Convert AddTrustedRootCertificate * Convert mSuccess and mFailure * Convert CreateBindingWithCallback --- examples/platform/linux/AppMain.cpp | 18 +- src/controller/CHIPDeviceController.cpp | 320 ++++++++++++------------ src/controller/CHIPDeviceController.h | 110 +++++--- 3 files changed, 240 insertions(+), 208 deletions(-) diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index ff34984ec8829c..03c44bd7d1ca5f 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -323,7 +323,7 @@ CHIP_ERROR ShutdownCommissioner() class PairingCommand : public Controller::DevicePairingDelegate, public Controller::DeviceAddressUpdateDelegate { public: - PairingCommand() : mSuccessCallback(OnSuccessResponse, this), mFailureCallback(OnFailureResponse, this){}; + PairingCommand(){}; /////////// DevicePairingDelegate Interface ///////// void OnStatusUpdate(Controller::DevicePairingDelegate::Status status) override; @@ -337,12 +337,9 @@ class PairingCommand : public Controller::DevicePairingDelegate, public Controll CHIP_ERROR UpdateNetworkAddress(); /* Callback when command results in success */ - static void OnSuccessResponse(void * context); + static void OnSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &); /* Callback when command results in failure */ - static void OnFailureResponse(void * context, uint8_t status); - - Callback::Callback mSuccessCallback; - Callback::Callback mFailureCallback; + static void OnFailureResponse(void * context, CHIP_ERROR error); }; PairingCommand gPairingCommand; @@ -401,12 +398,12 @@ void PairingCommand::OnPairingDeleted(CHIP_ERROR err) } } -void PairingCommand::OnSuccessResponse(void * context) +void PairingCommand::OnSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &) { ChipLogProgress(Controller, "OnSuccessResponse"); } -void PairingCommand::OnFailureResponse(void * context, uint8_t status) +void PairingCommand::OnFailureResponse(void * context, CHIP_ERROR error) { ChipLogProgress(Controller, "OnFailureResponse"); } @@ -423,15 +420,12 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) // - the cluster(s) chosen should come from the App Platform constexpr EndpointId kBindingClusterEndpoint = 0; - Callback::Cancelable * successCallback = mSuccessCallback.Cancel(); - Callback::Cancelable * failureCallback = mFailureCallback.Cancel(); - GroupId groupId = kUndefinedGroupId; EndpointId endpointId = 1; ClusterId clusterId = kInvalidClusterId; gCommissioner.CreateBindingWithCallback(nodeId, kBindingClusterEndpoint, gLocalId, groupId, endpointId, clusterId, - successCallback, failureCallback); + OnSuccessResponse, OnFailureResponse); } else { diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 6c433f6b7afdf1..44229a598012d0 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -88,6 +88,7 @@ using namespace chip::Inet; using namespace chip::System; using namespace chip::Transport; using namespace chip::Credentials; +using namespace chip::app::Clusters; // For some applications those does not implement IMDelegate, the DeviceControllerInteractionModelDelegate will dispatch the // response to IMDefaultResponseCallback CHIPClientCallbacks, for the applications those implemented IMDelegate, this function will @@ -107,9 +108,7 @@ using namespace chip::Protocols::UserDirectedCommissioning; constexpr uint32_t kSessionEstablishmentTimeout = 40 * kMillisecondsPerSecond; -DeviceController::DeviceController() : - mOpenPairingSuccessCallback(OnOpenPairingWindowSuccessResponse, this), - mOpenPairingFailureCallback(OnOpenPairingWindowFailureResponse, this) +DeviceController::DeviceController() { mState = State::NotInitialized; mStorageDelegate = nullptr; @@ -379,7 +378,7 @@ void DeviceController::OnPIDReadResponse(void * context, uint16_t value) if (controller->OpenCommissioningWindowInternal() != CHIP_NO_ERROR) { - OnOpenPairingWindowFailureResponse(context, 0); + OnOpenPairingWindowFailureResponse(context, CHIP_NO_ERROR); } } @@ -396,7 +395,7 @@ void DeviceController::OnVIDReadResponse(void * context, VendorId value) if (device == nullptr) { ChipLogError(Controller, "Could not find device for opening commissioning window"); - OnOpenPairingWindowFailureResponse(context, 0); + OnOpenPairingWindowFailureResponse(context, CHIP_NO_ERROR); return; } @@ -408,20 +407,17 @@ void DeviceController::OnVIDReadResponse(void * context, VendorId value) OnVIDPIDReadFailureResponse) != CHIP_NO_ERROR) { ChipLogError(Controller, "Could not read PID for opening commissioning window"); - OnOpenPairingWindowFailureResponse(context, 0); + OnOpenPairingWindowFailureResponse(context, CHIP_NO_ERROR); } } void DeviceController::OnVIDPIDReadFailureResponse(void * context, CHIP_ERROR error) { ChipLogProgress(Controller, "Failed to read VID/PID for the device. error %" CHIP_ERROR_FORMAT, error.Format()); - // TODO: The second arg here is wrong, but we need to fix the signature of - // OnOpenPairingWindowFailureResponse and how we send some commands to fix - // that. - OnOpenPairingWindowFailureResponse(context, to_underlying(app::StatusIB(error).mStatus)); + OnOpenPairingWindowFailureResponse(context, error); } -void DeviceController::OnOpenPairingWindowSuccessResponse(void * context) +void DeviceController::OnOpenPairingWindowSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &) { ChipLogProgress(Controller, "Successfully opened pairing window on the device"); DeviceController * controller = static_cast(context); @@ -433,17 +429,12 @@ void DeviceController::OnOpenPairingWindowSuccessResponse(void * context) } } -void DeviceController::OnOpenPairingWindowFailureResponse(void * context, uint8_t status) +void DeviceController::OnOpenPairingWindowFailureResponse(void * context, CHIP_ERROR error) { - ChipLogError(Controller, "Failed to open pairing window on the device. Status %d", status); + ChipLogError(Controller, "Failed to open pairing window on the device. Status %s", chip::ErrorStr(error)); DeviceController * controller = static_cast(context); if (controller->mCommissioningWindowCallback != nullptr) { - CHIP_ERROR error = CHIP_ERROR_INVALID_PASE_PARAMETER; - if (status == EmberAfStatusCode::EMBER_ZCL_STATUS_CODE_BUSY) - { - error = CHIP_ERROR_ANOTHER_COMMISSIONING_IN_PROGRESS; - } controller->mCommissioningWindowCallback->mCall(controller->mCommissioningWindowCallback->mContext, controller->mDeviceWithCommissioningWindowOpen, error, SetupPayload()); } @@ -520,9 +511,6 @@ CHIP_ERROR DeviceController::OpenCommissioningWindowInternal() chip::Controller::AdministratorCommissioningCluster cluster; cluster.Associate(device, kAdministratorCommissioningClusterEndpoint); - Callback::Cancelable * successCallback = mOpenPairingSuccessCallback.Cancel(); - Callback::Cancelable * failureCallback = mOpenPairingFailureCallback.Cancel(); - if (mCommissioningWindowOption != CommissioningWindowOption::kOriginalSetupCode) { ByteSpan salt(Uint8::from_const_char(kSpake2pKeyExchangeSalt), strlen(kSpake2pKeyExchangeSalt)); @@ -538,9 +526,16 @@ CHIP_ERROR DeviceController::OpenCommissioningWindowInternal() memcpy(serializedVerifier, verifier.mW0, kSpake2p_WS_Length); memcpy(&serializedVerifier[kSpake2p_WS_Length], verifier.mL, kSpake2p_WS_Length); - ReturnErrorOnFailure(cluster.OpenCommissioningWindow( - successCallback, failureCallback, mCommissioningWindowTimeout, ByteSpan(serializedVerifier, sizeof(serializedVerifier)), - mSetupPayload.discriminator, mCommissioningWindowIteration, salt, mPAKEVerifierID++)); + AdministratorCommissioning::Commands::OpenCommissioningWindow::Type request; + request.commissioningTimeout = mCommissioningWindowTimeout; + request.PAKEVerifier = ByteSpan(serializedVerifier); + request.discriminator = mSetupPayload.discriminator; + request.iterations = mCommissioningWindowIteration; + request.salt = salt; + request.passcodeID = mPAKEVerifierID++; + + ReturnErrorOnFailure( + cluster.InvokeCommand(request, this, OnOpenPairingWindowSuccessResponse, OnOpenPairingWindowFailureResponse)); char payloadBuffer[QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength]; @@ -554,7 +549,10 @@ CHIP_ERROR DeviceController::OpenCommissioningWindowInternal() } else { - ReturnErrorOnFailure(cluster.OpenBasicCommissioningWindow(successCallback, failureCallback, mCommissioningWindowTimeout)); + AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Type request; + request.commissioningTimeout = mCommissioningWindowTimeout; + ReturnErrorOnFailure( + cluster.InvokeCommand(request, this, OnOpenPairingWindowSuccessResponse, OnOpenPairingWindowFailureResponse)); } return CHIP_NO_ERROR; @@ -563,8 +561,8 @@ CHIP_ERROR DeviceController::OpenCommissioningWindowInternal() CHIP_ERROR DeviceController::CreateBindingWithCallback(chip::NodeId deviceId, chip::EndpointId deviceEndpointId, chip::NodeId bindingNodeId, chip::GroupId bindingGroupId, chip::EndpointId bindingEndpointId, chip::ClusterId bindingClusterId, - Callback::Cancelable * onSuccessCallback, - Callback::Cancelable * onFailureCallback) + CommandResponseSuccessCallback successCb, + CommandResponseFailureCallback failureCb) { PeerId peerId; peerId.SetNodeId(deviceId); @@ -580,8 +578,12 @@ CHIP_ERROR DeviceController::CreateBindingWithCallback(chip::NodeId deviceId, ch chip::Controller::BindingCluster cluster; cluster.Associate(device, deviceEndpointId); - ReturnErrorOnFailure( - cluster.Bind(onSuccessCallback, onFailureCallback, bindingNodeId, bindingGroupId, bindingEndpointId, bindingClusterId)); + Binding::Commands::Bind::Type request; + request.nodeId = bindingNodeId; + request.groupId = bindingGroupId; + request.endpointId = bindingEndpointId; + request.clusterId = bindingClusterId; + ReturnErrorOnFailure(cluster.InvokeCommand(request, this, successCb, failureCb)); ChipLogDetail(Controller, "Sent Bind command request, waiting for response"); return CHIP_NO_ERROR; @@ -646,12 +648,6 @@ ControllerDeviceInitParams DeviceController::GetControllerDeviceInitParams() } DeviceCommissioner::DeviceCommissioner() : - mSuccess(BasicSuccess, this), mFailure(BasicFailure, this), mCertificateChainResponseCallback(OnCertificateChainResponse, this), - mAttestationResponseCallback(OnAttestationResponse, this), mOpCSRResponseCallback(OnOperationalCertificateSigningRequest, this), - mNOCResponseCallback(OnOperationalCertificateAddResponse, this), mRootCertResponseCallback(OnRootCertSuccessResponse, this), - mOnCertificateChainFailureCallback(OnCertificateChainFailureResponse, this), - mOnAttestationFailureCallback(OnAttestationFailureResponse, this), mOnCSRFailureCallback(OnCSRFailureResponse, this), - mOnCertFailureCallback(OnAddNOCFailureResponse, this), mOnRootCertFailureCallback(OnRootCertFailureResponse, this), mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this), mDeviceAttestationInformationVerificationCallback(OnDeviceAttestationInformationVerification, this), mDeviceNOCChainCallback(OnDeviceNOCChainGeneration, this), mSetUpCodePairer(this), mAutoCommissioner(this) @@ -1060,36 +1056,30 @@ CHIP_ERROR DeviceCommissioner::SendCertificateChainRequestCommand(DeviceProxy * { ChipLogDetail(Controller, "Sending Certificate Chain request to %p device", device); VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - chip::Controller::OperationalCredentialsCluster cluster; - cluster.Associate(device, 0); - Callback::Cancelable * successCallback = mCertificateChainResponseCallback.Cancel(); - Callback::Cancelable * failureCallback = mOnCertificateChainFailureCallback.Cancel(); + OperationalCredentials::Commands::CertificateChainRequest::Type request; + request.certificateType = certificateType; + return SendCommand(device, request, OnCertificateChainResponse, + OnCertificateChainFailureResponse); - ReturnErrorOnFailure(cluster.CertificateChainRequest(successCallback, failureCallback, certificateType)); return CHIP_NO_ERROR; } -void DeviceCommissioner::OnCertificateChainFailureResponse(void * context, uint8_t status) +void DeviceCommissioner::OnCertificateChainFailureResponse(void * context, CHIP_ERROR error) { - ChipLogProgress(Controller, "Device failed to receive the Certificate Chain request Response: 0x%02x", status); + ChipLogProgress(Controller, "Device failed to receive the Certificate Chain request Response: %s", chip::ErrorStr(error)); DeviceCommissioner * commissioner = reinterpret_cast(context); - commissioner->mCertificateChainResponseCallback.Cancel(); - commissioner->mOnCertificateChainFailureCallback.Cancel(); - // TODO: Map error status to correct error code - commissioner->CommissioningStageComplete(CHIP_ERROR_INTERNAL); + commissioner->CommissioningStageComplete(error); } -void DeviceCommissioner::OnCertificateChainResponse(void * context, ByteSpan certificate) +void DeviceCommissioner::OnCertificateChainResponse( + void * context, const chip::app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & response) { ChipLogProgress(Controller, "Received certificate chain from the device"); DeviceCommissioner * commissioner = reinterpret_cast(context); - commissioner->mCertificateChainResponseCallback.Cancel(); - commissioner->mOnCertificateChainFailureCallback.Cancel(); - CommissioningDelegate::CommissioningReport report; - report.Set(RequestedCertificate(certificate)); + report.Set(RequestedCertificate(response.certificate)); commissioner->CommissioningStageComplete(CHIP_NO_ERROR, report); } @@ -1098,37 +1088,31 @@ CHIP_ERROR DeviceCommissioner::SendAttestationRequestCommand(DeviceProxy * devic { ChipLogDetail(Controller, "Sending Attestation request to %p device", device); VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - chip::Controller::OperationalCredentialsCluster cluster; - cluster.Associate(device, 0); - Callback::Cancelable * successCallback = mAttestationResponseCallback.Cancel(); - Callback::Cancelable * failureCallback = mOnAttestationFailureCallback.Cancel(); + OperationalCredentials::Commands::AttestationRequest::Type request; + request.attestationNonce = attestationNonce; - ReturnErrorOnFailure(cluster.AttestationRequest(successCallback, failureCallback, attestationNonce)); + ReturnErrorOnFailure( + SendCommand(device, request, OnAttestationResponse, OnAttestationFailureResponse)); ChipLogDetail(Controller, "Sent Attestation request, waiting for the Attestation Information"); return CHIP_NO_ERROR; } -void DeviceCommissioner::OnAttestationFailureResponse(void * context, uint8_t status) +void DeviceCommissioner::OnAttestationFailureResponse(void * context, CHIP_ERROR error) { - ChipLogProgress(Controller, "Device failed to receive the Attestation Information Response: 0x%02x", status); + ChipLogProgress(Controller, "Device failed to receive the Attestation Information Response: %s", chip::ErrorStr(error)); DeviceCommissioner * commissioner = reinterpret_cast(context); - commissioner->mAttestationResponseCallback.Cancel(); - commissioner->mOnAttestationFailureCallback.Cancel(); - // TODO: Map error status to correct error code - commissioner->CommissioningStageComplete(CHIP_ERROR_INTERNAL); + commissioner->CommissioningStageComplete(error); } -void DeviceCommissioner::OnAttestationResponse(void * context, chip::ByteSpan attestationElements, chip::ByteSpan signature) +void DeviceCommissioner::OnAttestationResponse(void * context, + const OperationalCredentials::Commands::AttestationResponse::DecodableType & data) { ChipLogProgress(Controller, "Received Attestation Information from the device"); DeviceCommissioner * commissioner = reinterpret_cast(context); - commissioner->mAttestationResponseCallback.Cancel(); - commissioner->mOnAttestationFailureCallback.Cancel(); - CommissioningDelegate::CommissioningReport report; - report.Set(AttestationResponse(attestationElements, signature)); + report.Set(AttestationResponse(data.attestationElements, data.signature)); commissioner->CommissioningStageComplete(CHIP_NO_ERROR, report); } @@ -1188,38 +1172,31 @@ CHIP_ERROR DeviceCommissioner::SendOperationalCertificateSigningRequestCommand(D { ChipLogDetail(Controller, "Sending OpCSR request to %p device", device); VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - chip::Controller::OperationalCredentialsCluster cluster; - cluster.Associate(device, 0); - Callback::Cancelable * successCallback = mOpCSRResponseCallback.Cancel(); - Callback::Cancelable * failureCallback = mOnCSRFailureCallback.Cancel(); - ReturnErrorOnFailure(cluster.OpCSRRequest(successCallback, failureCallback, csrNonce)); + OperationalCredentials::Commands::OpCSRRequest::Type request; + request.CSRNonce = csrNonce; + ReturnErrorOnFailure( + SendCommand(device, request, OnOperationalCertificateSigningRequest, OnCSRFailureResponse)); ChipLogDetail(Controller, "Sent OpCSR request, waiting for the CSR"); return CHIP_NO_ERROR; } -void DeviceCommissioner::OnCSRFailureResponse(void * context, uint8_t status) +void DeviceCommissioner::OnCSRFailureResponse(void * context, CHIP_ERROR error) { - ChipLogProgress(Controller, "Device failed to receive the CSR request Response: 0x%02x", status); + ChipLogProgress(Controller, "Device failed to receive the CSR request Response: %s", chip::ErrorStr(error)); DeviceCommissioner * commissioner = static_cast(context); - commissioner->mOpCSRResponseCallback.Cancel(); - commissioner->mOnCSRFailureCallback.Cancel(); - // TODO: Map error status to correct error code - commissioner->CommissioningStageComplete(CHIP_ERROR_INTERNAL); + commissioner->CommissioningStageComplete(error); } -void DeviceCommissioner::OnOperationalCertificateSigningRequest(void * context, ByteSpan NOCSRElements, - ByteSpan AttestationSignature) +void DeviceCommissioner::OnOperationalCertificateSigningRequest( + void * context, const OperationalCredentials::Commands::OpCSRResponse::DecodableType & data) { ChipLogProgress(Controller, "Received certificate signing request from the device"); DeviceCommissioner * commissioner = static_cast(context); - commissioner->mOpCSRResponseCallback.Cancel(); - commissioner->mOnCSRFailureCallback.Cancel(); - CommissioningDelegate::CommissioningReport report; - report.Set(AttestationResponse(NOCSRElements, AttestationSignature)); + report.Set(AttestationResponse(data.NOCSRElements, data.attestationSignature)); commissioner->CommissioningStageComplete(CHIP_NO_ERROR, report); } @@ -1287,13 +1264,16 @@ CHIP_ERROR DeviceCommissioner::SendOperationalCertificate(DeviceProxy * device, const NodeId adminSubject) { VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - chip::Controller::OperationalCredentialsCluster cluster; - cluster.Associate(device, 0); - Callback::Cancelable * successCallback = mNOCResponseCallback.Cancel(); - Callback::Cancelable * failureCallback = mOnCertFailureCallback.Cancel(); + OperationalCredentials::Commands::AddNOC::Type request; + request.NOCValue = nocCertBuf; + request.ICACValue = chip::Optional(icaCertBuf); + request.IPKValue = ipk; + request.caseAdminNode = adminSubject; + request.adminVendorId = mVendorId; - ReturnErrorOnFailure(cluster.AddNOC(successCallback, failureCallback, nocCertBuf, icaCertBuf, ipk, adminSubject, mVendorId)); + ReturnErrorOnFailure(SendCommand(mDeviceBeingCommissioned, request, + OnOperationalCertificateAddResponse, OnAddNOCFailureResponse)); ChipLogProgress(Controller, "Sent operational certificate to the device"); @@ -1327,20 +1307,17 @@ CHIP_ERROR DeviceCommissioner::ConvertFromNodeOperationalCertStatus(uint8_t err) return CHIP_ERROR_CERT_LOAD_FAILED; } -void DeviceCommissioner::OnAddNOCFailureResponse(void * context, uint8_t status) +void DeviceCommissioner::OnAddNOCFailureResponse(void * context, CHIP_ERROR error) { - ChipLogProgress(Controller, "Device failed to receive the operational certificate Response: 0x%02x", status); + ChipLogProgress(Controller, "Device failed to receive the operational certificate Response: %s", chip::ErrorStr(error)); DeviceCommissioner * commissioner = static_cast(context); - commissioner->mOpCSRResponseCallback.Cancel(); - commissioner->mOnCertFailureCallback.Cancel(); - // TODO: Map error status to correct error code - commissioner->CommissioningStageComplete(CHIP_ERROR_INTERNAL); + commissioner->CommissioningStageComplete(error); } -void DeviceCommissioner::OnOperationalCertificateAddResponse(void * context, uint8_t StatusCode, uint8_t FabricIndex, - CharSpan DebugText) +void DeviceCommissioner::OnOperationalCertificateAddResponse( + void * context, const OperationalCredentials::Commands::NOCResponse::DecodableType & data) { - ChipLogProgress(Controller, "Device returned status %d on receiving the NOC", StatusCode); + ChipLogProgress(Controller, "Device returned status %d on receiving the NOC", data.statusCode); DeviceCommissioner * commissioner = static_cast(context); CHIP_ERROR err = CHIP_NO_ERROR; @@ -1348,12 +1325,9 @@ void DeviceCommissioner::OnOperationalCertificateAddResponse(void * context, uin VerifyOrExit(commissioner->mState == State::Initialized, err = CHIP_ERROR_INCORRECT_STATE); - commissioner->mOpCSRResponseCallback.Cancel(); - commissioner->mOnCertFailureCallback.Cancel(); - VerifyOrExit(commissioner->mDeviceBeingCommissioned != nullptr, err = CHIP_ERROR_INCORRECT_STATE); - err = ConvertFromNodeOperationalCertStatus(StatusCode); + err = ConvertFromNodeOperationalCertStatus(data.statusCode); SuccessOrExit(err); device = commissioner->mDeviceBeingCommissioned; @@ -1374,38 +1348,28 @@ CHIP_ERROR DeviceCommissioner::SendTrustedRootCertificate(DeviceProxy * device, ChipLogProgress(Controller, "Sending root certificate to the device"); - chip::Controller::OperationalCredentialsCluster cluster; - cluster.Associate(device, 0); - - Callback::Cancelable * successCallback = mRootCertResponseCallback.Cancel(); - Callback::Cancelable * failureCallback = mOnRootCertFailureCallback.Cancel(); - - ReturnErrorOnFailure(cluster.AddTrustedRootCertificate(successCallback, failureCallback, rcac)); + OperationalCredentials::Commands::AddTrustedRootCertificate::Type request; + request.rootCertificate = rcac; + ReturnErrorOnFailure( + SendCommand(device, request, OnRootCertSuccessResponse, OnRootCertFailureResponse)); ChipLogProgress(Controller, "Sent root certificate to the device"); return CHIP_NO_ERROR; } -void DeviceCommissioner::OnRootCertSuccessResponse(void * context) +void DeviceCommissioner::OnRootCertSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &) { ChipLogProgress(Controller, "Device confirmed that it has received the root certificate"); DeviceCommissioner * commissioner = static_cast(context); - - commissioner->mRootCertResponseCallback.Cancel(); - commissioner->mOnRootCertFailureCallback.Cancel(); - commissioner->CommissioningStageComplete(CHIP_NO_ERROR); } -void DeviceCommissioner::OnRootCertFailureResponse(void * context, uint8_t status) +void DeviceCommissioner::OnRootCertFailureResponse(void * context, CHIP_ERROR error) { - ChipLogProgress(Controller, "Device failed to receive the root certificate Response: 0x%02x", status); + ChipLogProgress(Controller, "Device failed to receive the root certificate Response: %s", chip::ErrorStr(error)); DeviceCommissioner * commissioner = static_cast(context); - commissioner->mRootCertResponseCallback.Cancel(); - commissioner->mOnRootCertFailureCallback.Cancel(); - // TODO: Map error status to correct error code - commissioner->CommissioningStageComplete(CHIP_ERROR_INTERNAL); + commissioner->CommissioningStageComplete(error); } CHIP_ERROR DeviceCommissioner::OnOperationalCredentialsProvisioningCompletion(CommissioneeDeviceProxy * device) @@ -1506,18 +1470,11 @@ void DeviceCommissioner::OnNodeDiscoveryComplete(const chip::Dnssd::DiscoveredNo } #endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD -void BasicSuccess(void * context, uint16_t val) -{ - ChipLogProgress(Controller, "Received success response 0x%x\n", val); - DeviceCommissioner * commissioner = static_cast(context); - commissioner->CommissioningStageComplete(CHIP_NO_ERROR); -} - -void BasicFailure(void * context, uint8_t status) +void OnBasicFailure(void * context, CHIP_ERROR error) { - ChipLogProgress(Controller, "Received failure response %d\n", (int) status); + ChipLogProgress(Controller, "Received failure response %s\n", chip::ErrorStr(error)); DeviceCommissioner * commissioner = static_cast(context); - commissioner->CommissioningStageComplete(static_cast(status)); + commissioner->CommissioningStageComplete(error); } void DeviceCommissioner::CommissioningStageComplete(CHIP_ERROR err, CommissioningDelegate::CommissioningReport report) @@ -1641,6 +1598,51 @@ void AttributeReadFailure(void * context, CHIP_ERROR status) commissioner->CommissioningStageComplete(status); } +void DeviceCommissioner::OnArmFailSafe(void * context, + const GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data) +{ + // TODO: Use errorCode + ChipLogProgress(Controller, "Received ArmFailSafe response"); + DeviceCommissioner * commissioner = static_cast(context); + commissioner->CommissioningStageComplete(CHIP_NO_ERROR); +} + +void DeviceCommissioner::OnSetRegulatoryConfigResponse( + void * context, const GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data) +{ + // TODO: Use errorCode + ChipLogProgress(Controller, "Received SetRegulatoryConfig response"); + DeviceCommissioner * commissioner = static_cast(context); + commissioner->CommissioningStageComplete(CHIP_NO_ERROR); +} + +void DeviceCommissioner::OnNetworkConfigResponse(void * context, + const NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data) +{ + // TODO: Use networkingStatus + ChipLogProgress(Controller, "Received NetworkConfig response"); + DeviceCommissioner * commissioner = static_cast(context); + commissioner->CommissioningStageComplete(CHIP_NO_ERROR); +} + +void DeviceCommissioner::OnConnectNetworkResponse( + void * context, const NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data) +{ + // TODO: Use networkingStatus + ChipLogProgress(Controller, "Received ConnectNetwork response"); + DeviceCommissioner * commissioner = static_cast(context); + commissioner->CommissioningStageComplete(CHIP_NO_ERROR); +} + +void DeviceCommissioner::OnCommissioningCompleteResponse( + void * context, const GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & data) +{ + // TODO: Use errorCode + ChipLogProgress(Controller, "Received CommissioningComplete response"); + DeviceCommissioner * commissioner = static_cast(context); + commissioner->CommissioningStageComplete(CHIP_NO_ERROR); +} + void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, CommissioningStage step, CommissioningParameters & params, CommissioningDelegate * delegate, EndpointId endpoint, Optional timeout) @@ -1661,11 +1663,12 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio { case CommissioningStage::kArmFailsafe: { ChipLogProgress(Controller, "Arming failsafe"); - // TODO(cecille): Find a way to enumerate the clusters here. - GeneralCommissioningCluster genCom; // TODO: should get the endpoint information from the descriptor cluster. - SetupCluster(genCom, proxy, endpoint, timeout); - genCom.ArmFailSafe(mSuccess.Cancel(), mFailure.Cancel(), params.GetFailsafeTimerSeconds(), breadcrumb, kCommandTimeoutMs); + GeneralCommissioning::Commands::ArmFailSafe::Type request; + request.expiryLengthSeconds = params.GetFailsafeTimerSeconds(); + request.breadcrumb = breadcrumb; + request.timeoutMs = kCommandTimeoutMs; + SendCommand(proxy, request, OnArmFailSafe, OnBasicFailure, timeout); } break; case CommissioningStage::kGetNetworkTechnology: { @@ -1713,10 +1716,12 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio } chip::CharSpan countryCode(countryCodeStr, actualCountryCodeSize); - GeneralCommissioningCluster genCom; - SetupCluster(genCom, proxy, endpoint, timeout); - genCom.SetRegulatoryConfig(mSuccess.Cancel(), mFailure.Cancel(), regulatoryLocation, countryCode, breadcrumb, - kCommandTimeoutMs); + GeneralCommissioning::Commands::SetRegulatoryConfig::Type request; + request.location = static_cast(regulatoryLocation); + request.countryCode = countryCode; + request.breadcrumb = breadcrumb; + request.timeoutMs = kCommandTimeoutMs; + SendCommand(proxy, request, OnSetRegulatoryConfigResponse, OnBasicFailure, timeout); } break; case CommissioningStage::kSendPAICertificateRequest: @@ -1835,11 +1840,13 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio CommissioningStageComplete(CHIP_ERROR_INVALID_ARGUMENT); return; } + ChipLogProgress(Controller, "Adding wifi network"); - NetworkCommissioningCluster netCom; - SetupCluster(netCom, proxy, endpoint, timeout); - netCom.AddOrUpdateWiFiNetwork(mSuccess.Cancel(), mFailure.Cancel(), params.GetWiFiCredentials().Value().ssid, - params.GetWiFiCredentials().Value().credentials, breadcrumb); + NetworkCommissioning::Commands::AddOrUpdateWiFiNetwork::Type request; + request.ssid = params.GetWiFiCredentials().Value().ssid; + request.credentials = params.GetWiFiCredentials().Value().credentials; + request.breadcrumb = breadcrumb; + SendCommand(proxy, request, OnNetworkConfigResponse, OnBasicFailure); } break; case CommissioningStage::kThreadNetworkSetup: { @@ -1850,10 +1857,10 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio return; } ChipLogProgress(Controller, "Adding thread network"); - NetworkCommissioningCluster netCom; - SetupCluster(netCom, proxy, endpoint, timeout); - netCom.AddOrUpdateThreadNetwork(mSuccess.Cancel(), mFailure.Cancel(), params.GetThreadOperationalDataset().Value(), - breadcrumb); + NetworkCommissioning::Commands::AddOrUpdateThreadNetwork::Type request; + request.operationalDataset = params.GetThreadOperationalDataset().Value(); + request.breadcrumb = breadcrumb; + SendCommand(proxy, request, OnNetworkConfigResponse, OnBasicFailure); } break; case CommissioningStage::kWiFiNetworkEnable: { @@ -1864,9 +1871,10 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio return; } ChipLogProgress(Controller, "Enabling wifi network"); - NetworkCommissioningCluster netCom; - SetupCluster(netCom, proxy, endpoint, timeout); - netCom.ConnectNetwork(mSuccess.Cancel(), mFailure.Cancel(), params.GetWiFiCredentials().Value().ssid, breadcrumb); + NetworkCommissioning::Commands::ConnectNetwork::Type request; + request.networkID = params.GetWiFiCredentials().Value().ssid; + request.breadcrumb = breadcrumb; + SendCommand(proxy, request, OnConnectNetworkResponse, OnBasicFailure); } break; case CommissioningStage::kThreadNetworkEnable: { @@ -1881,9 +1889,10 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio return; } ChipLogProgress(Controller, "Enabling thread network"); - NetworkCommissioningCluster netCom; - SetupCluster(netCom, proxy, endpoint, timeout); - netCom.ConnectNetwork(mSuccess.Cancel(), mFailure.Cancel(), extendedPanId, breadcrumb); + NetworkCommissioning::Commands::ConnectNetwork::Type request; + request.networkID = extendedPanId; + request.breadcrumb = breadcrumb; + SendCommand(proxy, request, OnConnectNetworkResponse, OnBasicFailure); } break; case CommissioningStage::kFindOperational: { @@ -1898,9 +1907,8 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio break; case CommissioningStage::kSendComplete: { ChipLogProgress(Controller, "Calling commissioning complete"); - GeneralCommissioningCluster genCom; - SetupCluster(genCom, proxy, endpoint, timeout); - genCom.CommissioningComplete(mSuccess.Cancel(), mFailure.Cancel()); + GeneralCommissioning::Commands::CommissioningComplete::Type request; + SendCommand(proxy, request, OnCommissioningCompleteResponse, OnBasicFailure, timeout); } break; case CommissioningStage::kCleanup: @@ -1918,7 +1926,7 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio case CommissioningStage::kSecurePairing: break; } -} +} // namespace Controller } // namespace Controller } // namespace chip diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 71946f3d8e5427..8843f6e1024a2f 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -51,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -88,10 +88,7 @@ constexpr uint16_t kNumMaxActiveDevices = CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVI 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); +void OnBasicFailure(void * context, CHIP_ERROR err); struct ControllerInitParams { @@ -323,10 +320,11 @@ class DLL_EXPORT DeviceController : public SessionRecoveryDelegate, * * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error */ - CHIP_ERROR CreateBindingWithCallback(chip::NodeId deviceId, chip::EndpointId deviceEndpointId, chip::NodeId bindingNodeId, - chip::GroupId bindingGroupId, chip::EndpointId bindingEndpointId, - chip::ClusterId bindingClusterId, Callback::Cancelable * onSuccessCallback, - Callback::Cancelable * onFailureCallback); + CHIP_ERROR + CreateBindingWithCallback(chip::NodeId deviceId, chip::EndpointId deviceEndpointId, chip::NodeId bindingNodeId, + chip::GroupId bindingGroupId, chip::EndpointId bindingEndpointId, chip::ClusterId bindingClusterId, + CommandResponseSuccessCallback successCb, + CommandResponseFailureCallback failureCb); #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD void RegisterDeviceAddressUpdateDelegate(DeviceAddressUpdateDelegate * delegate) { mDeviceAddressUpdateDelegate = delegate; } @@ -412,9 +410,6 @@ class DLL_EXPORT DeviceController : public SessionRecoveryDelegate, private: void ReleaseOperationalDevice(OperationalDeviceProxy * device); - Callback::Callback mOpenPairingSuccessCallback; - Callback::Callback mOpenPairingFailureCallback; - static void OnPIDReadResponse(void * context, uint16_t value); static void OnVIDReadResponse(void * context, VendorId value); static void OnVIDPIDReadFailureResponse(void * context, CHIP_ERROR error); @@ -437,8 +432,8 @@ class DLL_EXPORT DeviceController : public SessionRecoveryDelegate, CommissioningWindowOption mCommissioningWindowOption; - static void OnOpenPairingWindowSuccessResponse(void * context); - static void OnOpenPairingWindowFailureResponse(void * context, uint8_t status); + static void OnOpenPairingWindowSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &); + static void OnOpenPairingWindowFailureResponse(void * context, CHIP_ERROR error); CHIP_ERROR ProcessControllerNOCChain(const ControllerInitParams & params); uint16_t mPAKEVerifierID = 1; @@ -751,13 +746,16 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, 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 OnCSRFailureResponse(void * context, CHIP_ERROR error); - static void OnCertificateChainFailureResponse(void * context, uint8_t status); - static void OnCertificateChainResponse(void * context, ByteSpan certificate); + static void OnCertificateChainFailureResponse(void * context, CHIP_ERROR error); + static void OnCertificateChainResponse( + void * context, const app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & response); - static void OnAttestationFailureResponse(void * context, uint8_t status); - static void OnAttestationResponse(void * context, chip::ByteSpan attestationElements, chip::ByteSpan signature); + static void OnAttestationFailureResponse(void * context, CHIP_ERROR error); + static void + OnAttestationResponse(void * context, + const app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType & data); /** * @brief @@ -765,20 +763,25 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, * (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. + * @param[in] data The response struct containing the following fields: + * NOCSRElements: CSR elements as per specifications section 11.22.5.6. NOCSR Elements. + * AttestationSignature: Cryptographic signature generated for the fields in the response + * message. */ - static void OnOperationalCertificateSigningRequest(void * context, ByteSpan NOCSRElements, ByteSpan AttestationSignature); + static void OnOperationalCertificateSigningRequest( + void * context, const app::Clusters::OperationalCredentials::Commands::OpCSRResponse::DecodableType & data); /* Callback when adding operational certs to device results in failure */ - static void OnAddNOCFailureResponse(void * context, uint8_t status); + static void OnAddNOCFailureResponse(void * context, CHIP_ERROR errro); /* 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); + static void + OnOperationalCertificateAddResponse(void * context, + const app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType & data); /* Callback when the device confirms that it has added the root certificate */ - static void OnRootCertSuccessResponse(void * context); + static void OnRootCertSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &); /* Callback called when adding root cert to device results in failure */ - static void OnRootCertFailureResponse(void * context, uint8_t status); + static void OnRootCertFailureResponse(void * context, CHIP_ERROR error); static void OnDeviceConnectedFn(void * context, OperationalDeviceProxy * device); static void OnDeviceConnectionFailureFn(void * context, PeerId peerId, CHIP_ERROR error); @@ -787,6 +790,19 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac, const ByteSpan & rcac, Optional ipk, Optional adminSubject); + static void OnArmFailSafe(void * context, + const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data); + static void OnSetRegulatoryConfigResponse( + void * context, + const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data); + static void + OnNetworkConfigResponse(void * context, + const chip::app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data); + static void OnConnectNetworkResponse( + void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data); + static void OnCommissioningCompleteResponse( + void * context, + const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & data); /** * @brief @@ -814,22 +830,36 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, CommissioneeDeviceProxy * FindCommissioneeDevice(NodeId id); void ReleaseCommissioneeDevice(CommissioneeDeviceProxy * device); - // Cluster callbacks for advancing commissioning flows - Callback::Callback mSuccess; - Callback::Callback mFailure; + template + CHIP_ERROR SendCommand(DeviceProxy * device, RequestObjectT request, + CommandResponseSuccessCallback successCb, + CommandResponseFailureCallback failureCb) + { + ClusterObjectT cluster; + cluster.Associate(device, 0); - static CHIP_ERROR ConvertFromNodeOperationalCertStatus(uint8_t err); + return cluster.InvokeCommand(request, this, successCb, failureCb); + } + + template + CHIP_ERROR SendCommand(DeviceProxy * device, RequestObjectT request, + CommandResponseSuccessCallback successCb, + CommandResponseFailureCallback failureCb, chip::Optional timeout) + { + ClusterObjectT cluster; + cluster.Associate(device, 0); + + if (timeout.HasValue()) + { + VerifyOrReturnError(chip::CanCastTo(timeout.Value().count()), CHIP_ERROR_INVALID_ARGUMENT); + chip::Optional timedInvokeRequestTimeoutInMs(static_cast(timeout.Value().count())); + return cluster.InvokeCommand(request, this, successCb, failureCb, timedInvokeRequestTimeoutInMs); + } - Callback::Callback mCertificateChainResponseCallback; - Callback::Callback mAttestationResponseCallback; - Callback::Callback mOpCSRResponseCallback; - Callback::Callback mNOCResponseCallback; - Callback::Callback mRootCertResponseCallback; - Callback::Callback mOnCertificateChainFailureCallback; - Callback::Callback mOnAttestationFailureCallback; - Callback::Callback mOnCSRFailureCallback; - Callback::Callback mOnCertFailureCallback; - Callback::Callback mOnRootCertFailureCallback; + return cluster.InvokeCommand(request, this, successCb, failureCb); + } + + static CHIP_ERROR ConvertFromNodeOperationalCertStatus(uint8_t err); Callback::Callback mOnDeviceConnectedCallback; Callback::Callback mOnDeviceConnectionFailureCallback;