Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ScanNetworks step to CHIPDeviceController #20766

Merged
merged 30 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
36bb9b3
DRAFT: add ScanNetworks step to CHIPDeviceController
chrisdecenzo Jul 14, 2022
0aec701
Add android hooks and callbacks for network scan
chrisdecenzo Jul 15, 2022
2ec5b41
Add controller parameters for failsafe timeout, and scans
chrisdecenzo Jul 15, 2022
f01e003
Add callback for ReadCommissioningInfo
chrisdecenzo Jul 15, 2022
9e9a142
straggler file
chrisdecenzo Jul 15, 2022
bd09776
address comments
chrisdecenzo Jul 15, 2022
1b263df
fix android build
chrisdecenzo Jul 15, 2022
0a982eb
DRAFT: add ScanNetworks step to CHIPDeviceController
chrisdecenzo Jul 14, 2022
bfcb784
Add android hooks and callbacks for network scan
chrisdecenzo Jul 15, 2022
cfd3351
Add controller parameters for failsafe timeout, and scans
chrisdecenzo Jul 15, 2022
4bcd7c4
Add callback for ReadCommissioningInfo
chrisdecenzo Jul 15, 2022
756ac8f
straggler file
chrisdecenzo Jul 15, 2022
ac0327f
address comments
chrisdecenzo Jul 15, 2022
b7b58b3
fix android build
chrisdecenzo Jul 15, 2022
4a4b93b
Restyle DRAFT: add ScanNetworks step to CHIPDeviceController (#20808)
restyled-io[bot] Jul 16, 2022
d61ae0d
fix CI
chrisdecenzo Jul 18, 2022
406e727
merge with latest, fix conflicts
chrisdecenzo Jul 18, 2022
2452d0f
fix kotlin build issue
chrisdecenzo Jul 18, 2022
946d0f0
fix java method signature lookup
chrisdecenzo Jul 18, 2022
f06a4f2
fix cirq tests, add name for ScanNetworks step
chrisdecenzo Jul 19, 2022
f1b5c64
attempt to fix cirq tests
chrisdecenzo Jul 20, 2022
3ae3de4
Address comments
chrisdecenzo Jul 26, 2022
8776a7e
Address comments
chrisdecenzo Jul 26, 2022
2282310
sync to master
chrisdecenzo Jul 26, 2022
f158c8e
fix stragglers, restyle
chrisdecenzo Jul 26, 2022
2a5e0a3
address feedback
chrisdecenzo Jul 28, 2022
90cf820
address feedback
chrisdecenzo Jul 28, 2022
16a7ecc
fix build
chrisdecenzo Jul 28, 2022
390b792
fix build
chrisdecenzo Jul 28, 2022
5083311
fix build
chrisdecenzo Jul 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/controller/AutoCommissioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,26 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio
}
return CommissioningStage::kArmFailsafe;
case CommissioningStage::kArmFailsafe:
if (mNeedsNetworkSetup)
{
// if there is a WiFi or a Thread endpoint, then perform scan
if ((mParams.GetAttemptWiFiNetworkScan() && mDeviceCommissioningInfo.network.wifi.endpoint != kInvalidEndpointId) ||
(mParams.GetAttemptThreadNetworkScan() && mDeviceCommissioningInfo.network.thread.endpoint != kInvalidEndpointId))
{
return CommissioningStage::kScanNetworks;
}
else
{
ChipLogProgress(Controller, "No NetworkScan enabled or WiFi/Thread endpoint not specified, skipping ScanNetworks");
}
}
else
{
ChipLogProgress(Controller, "Not a BLE connection, skipping ScanNetworks");
}
// fall through if no network scan is called for
FALLTHROUGH;
case CommissioningStage::kScanNetworks:
return CommissioningStage::kConfigRegulatory;
case CommissioningStage::kConfigRegulatory:
return CommissioningStage::kSendPAICertificateRequest;
Expand Down
2 changes: 2 additions & 0 deletions src/controller/AutoCommissioner.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class AutoCommissioner : public CommissioningDelegate

CHIP_ERROR CommissioningStepFinished(CHIP_ERROR err, CommissioningDelegate::CommissioningReport report) override;

ReadCommissioningInfo GetReadCommissioningInfo() const { return mDeviceCommissioningInfo; }
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved

protected:
CommissioningStage GetNextCommissioningStage(CommissioningStage currentStage, CHIP_ERROR & lastErr);
DeviceCommissioner * GetCommissioner() { return mCommissioner; }
Expand Down
124 changes: 124 additions & 0 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,41 @@ void DeviceCommissioner::SendCommissioningCompleteCallbacks(NodeId nodeId, const
}
}

void DeviceCommissioner::PauseCommissioning()
{
VerifyOrReturn(mDeviceBeingCommissioned != nullptr);
mCommissioningPaused = true;
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
}

void DeviceCommissioner::ResumeCommissioning()
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
{
VerifyOrReturn(mCommissioningPaused);
VerifyOrReturn(mDeviceBeingCommissioned != nullptr);

NodeId nodeId = mDeviceBeingCommissioned->GetDeviceId();
DeviceProxy * proxy = mDeviceBeingCommissioned;
mDeviceBeingCommissioned = nullptr;
CommissioningDelegate::CommissioningReport report;
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved

if (mCommissioningDelegate == nullptr)
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
{
return;
}
report.stageCompleted = mCommissioningStage;
CHIP_ERROR status = mCommissioningDelegate->CommissioningStepFinished(mCommissioningPausedErr, report);
if (status != CHIP_NO_ERROR)
{
// Commissioning delegate will only return error if it failed to perform the appropriate commissioning step.
// In this case, we should complete the commissioning for it.
CompletionStatus completionStatus;
completionStatus.err = status;
completionStatus.failedStage = MakeOptional(report.stageCompleted);
mCommissioningStage = CommissioningStage::kCleanup;
mDeviceBeingCommissioned = proxy;
CleanupCommissioning(proxy, nodeId, completionStatus);
}
}

void DeviceCommissioner::CommissioningStageComplete(CHIP_ERROR err, CommissioningDelegate::CommissioningReport report)
{
// Once this stage is complete, reset mDeviceBeingCommissioned - this will be reset when the delegate calls the next step.
Expand All @@ -1569,6 +1604,13 @@ void DeviceCommissioner::CommissioningStageComplete(CHIP_ERROR err, Commissionin
{
mPairingDelegate->OnCommissioningStatusUpdate(PeerId(GetCompressedFabricId(), nodeId), mCommissioningStage, err);
}

if (mCommissioningPaused)
{
mDeviceBeingCommissioned = proxy;
mCommissioningPausedErr = err;
return;
}
if (mCommissioningDelegate == nullptr)
{
return;
Expand Down Expand Up @@ -1724,20 +1766,24 @@ void DeviceCommissioner::OnDone(app::ReadClient *)
{
if (features.Has(app::Clusters::NetworkCommissioning::NetworkCommissioningFeature::kWiFiNetworkInterface))
{
ChipLogError(Controller, "----- NetworkCommissioning Features: has WiFi.");
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
info.network.wifi.endpoint = path.mEndpointId;
}
else if (features.Has(
app::Clusters::NetworkCommissioning::NetworkCommissioningFeature::kThreadNetworkInterface))
{
ChipLogError(Controller, "----- NetworkCommissioning Features: has Thread.");
info.network.thread.endpoint = path.mEndpointId;
}
else if (features.Has(
app::Clusters::NetworkCommissioning::NetworkCommissioningFeature::kEthernetNetworkInterface))
{
ChipLogError(Controller, "----- NetworkCommissioning Features: has Ethernet.");
info.network.eth.endpoint = path.mEndpointId;
}
else
{
ChipLogError(Controller, "----- NetworkCommissioning Features: no features.");
// TODO: Gross workaround for the empty feature map on all clusters. Remove.
if (info.network.thread.endpoint == kInvalidEndpointId)
{
Expand Down Expand Up @@ -1824,6 +1870,74 @@ void DeviceCommissioner::OnSetRegulatoryConfigResponse(
commissioner->CommissioningStageComplete(err, report);
}

void DeviceCommissioner::OnScanNetworksFailure(void * context, CHIP_ERROR error)
{
ChipLogProgress(Controller, "Received ScanNetworks failure response %s\n", chip::ErrorStr(error));
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved

DeviceCommissioner * commissioner = static_cast<DeviceCommissioner *>(context);
if (commissioner->GetPairingDelegate() != nullptr)
{
commissioner->GetPairingDelegate()->OnScanNetworksFailure(error);
}
// need to advance to next step
// clear error so that we don't abort the commissioning when ScanNetworks fails
commissioner->CommissioningStageComplete(CHIP_NO_ERROR);
}

void DeviceCommissioner::OnScanNetworksResponse(void * context,
const NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & data)
{
CommissioningDelegate::CommissioningReport report;

ChipLogProgress(Controller, "Received ScanNetwork response, networkingStatus=%u debugText=%s",
to_underlying(data.networkingStatus),
(data.debugText.HasValue() ? std::string(data.debugText.Value().data(), data.debugText.Value().size()).c_str()
: "none provided"));
if (data.networkingStatus == NetworkCommissioning::NetworkCommissioningStatus::kSuccess)
{
if (data.wiFiScanResults.HasValue())
{
ChipLogProgress(Controller, "ScanNetwork response, has WiFi results");

auto iter_WiFiScanResultsInsideOptional_1 = data.wiFiScanResults.Value().begin();
while (iter_WiFiScanResultsInsideOptional_1.Next())
{
auto & entry_1 = iter_WiFiScanResultsInsideOptional_1.GetValue();
ChipLogProgress(Controller, "ScanNetwork response, next WiFi channel=%d", entry_1.channel);
}
}
else
{
ChipLogProgress(Controller, "ScanNetwork response, no WiFi results");
}
if (data.threadScanResults.HasValue())
{
ChipLogProgress(Controller, "ScanNetwork response, has Thread results");

auto iter_ThreadScanResultsInsideOptional_1 = data.threadScanResults.Value().begin();
while (iter_ThreadScanResultsInsideOptional_1.Next())
{
auto & entry_1 = iter_ThreadScanResultsInsideOptional_1.GetValue();
ChipLogProgress(Controller, "ScanNetwork response, next Thread network name=%s",
std::string(entry_1.networkName.data(), entry_1.networkName.size()).c_str());
}
}
else
{
ChipLogProgress(Controller, "ScanNetwork response, no Thread results");
}
}

DeviceCommissioner * commissioner = static_cast<DeviceCommissioner *>(context);

if (commissioner->GetPairingDelegate() != nullptr)
{
commissioner->GetPairingDelegate()->OnScanNetworksSuccess(data);
}
// need to advance to next step
commissioner->CommissioningStageComplete(CHIP_NO_ERROR);
}

void DeviceCommissioner::OnNetworkConfigResponse(void * context,
const NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data)
{
Expand Down Expand Up @@ -1953,6 +2067,16 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
mReadClient = std::move(readClient);
}
break;
case CommissioningStage::kScanNetworks: {
NetworkCommissioning::Commands::ScanNetworks::Type request;
if (params.GetWiFiCredentials().HasValue())
{
request.ssid.Emplace(params.GetWiFiCredentials().Value().ssid);
}
request.breadcrumb.Emplace(breadcrumb);
SendCommand<NetworkCommissioningCluster>(proxy, request, OnScanNetworksResponse, OnScanNetworksFailure, endpoint, timeout);
break;
}
case CommissioningStage::kConfigRegulatory: {
// To set during config phase:
// UTC time
Expand Down
18 changes: 18 additions & 0 deletions src/controller/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,18 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
*/
CHIP_ERROR ValidateAttestationInfo(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);

/**
* @brief
* This function puts the commissioner in a paused state to prevent advancing to the next stage.
* It is expected that a DevicePairingDelegate may call this method when processing the
* OnCommissioningStatusUpdate, for example, in order to obtain network credentials from the user based
* upon the results of the NetworkScan.
* Use ResumeCommissioning to continue the commissioning process.
*
*/
void PauseCommissioning();
void ResumeCommissioning();

/**
* @brief
* Sends CommissioningStepComplete report to the commissioning delegate. Function will fill in current step.
Expand Down Expand Up @@ -764,6 +776,10 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
void * context,
const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data);
static void
OnScanNetworksResponse(void * context,
const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & data);
static void OnScanNetworksFailure(void * context, CHIP_ERROR err);
static void
OnNetworkConfigResponse(void * context,
const chip::app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data);
static void OnConnectNetworkResponse(
Expand Down Expand Up @@ -871,6 +887,8 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
Platform::UniquePtr<app::ReadClient> mReadClient;
Credentials::AttestationVerificationResult mAttestationResult;
Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;
bool mCommissioningPaused = false;
CHIP_ERROR mCommissioningPausedErr = CHIP_NO_ERROR;
};

} // namespace Controller
Expand Down
17 changes: 17 additions & 0 deletions src/controller/CommissioningDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum CommissioningStage : uint8_t
kSecurePairing,
kReadCommissioningInfo,
kArmFailsafe,
kScanNetworks,
kConfigRegulatory,
kSendPAICertificateRequest,
kSendDACCertificateRequest,
Expand Down Expand Up @@ -352,6 +353,20 @@ class CommissioningParameters

Credentials::DeviceAttestationDelegate * GetDeviceAttestationDelegate() const { return mDeviceAttestationDelegate; }

bool GetAttemptWiFiNetworkScan() const { return mAttemptWiFiNetworkScan; }
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
CommissioningParameters & SetAttemptWiFiNetworkScan(bool attemptWiFiNetworkScan)
{
mAttemptWiFiNetworkScan = attemptWiFiNetworkScan;
return *this;
}

bool GetAttemptThreadNetworkScan() const { return mAttemptThreadNetworkScan; }
CommissioningParameters & SetAttemptThreadNetworkScan(bool attemptThreadNetworkScan)
{
mAttemptThreadNetworkScan = attemptThreadNetworkScan;
return *this;
}

private:
// Items that can be set by the commissioner
Optional<uint16_t> mFailsafeTimerSeconds;
Expand Down Expand Up @@ -379,6 +394,8 @@ class CommissioningParameters
CompletionStatus completionStatus;
Credentials::DeviceAttestationDelegate * mDeviceAttestationDelegate =
nullptr; // Delegate to handle device attestation failures during commissioning
bool mAttemptWiFiNetworkScan = false;
bool mAttemptThreadNetworkScan = true; // TODO: consider whether default value should be enabled or disabled
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
};

struct RequestedCertificate
Expand Down
14 changes: 14 additions & 0 deletions src/controller/DevicePairingDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ class DLL_EXPORT DevicePairingDelegate
{}

virtual void OnCommissioningStatusUpdate(PeerId peerId, CommissioningStage stageCompleted, CHIP_ERROR error) {}

/**
* @brief
* Called with the NetworkScanResponse returned from the target
*/
virtual void OnScanNetworksSuccess(
const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & dataResponse)
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
{}

/**
* @brief
* Called when the NetworkScan request fails.
*/
virtual void OnScanNetworksFailure(CHIP_ERROR error) {}
};

} // namespace Controller
Expand Down
Loading