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

Implement unpairDevice API in android and chip-tool #24127

Merged
merged 15 commits into from
Jan 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import com.google.chip.chiptool.provisioning.AddressCommissioningFragment
import com.google.chip.chiptool.provisioning.DeviceProvisioningFragment
import com.google.chip.chiptool.provisioning.EnterNetworkFragment
import com.google.chip.chiptool.provisioning.ProvisionNetworkType
import com.google.chip.chiptool.provisioning.UnpairDeviceFragment
import com.google.chip.chiptool.setuppayloadscanner.BarcodeFragment
import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceDetailsFragment
import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceInfo
Expand Down Expand Up @@ -191,6 +192,10 @@ class CHIPToolActivity :
showFragment(BarcodeFragment.newInstance())
}

override fun handleUnpairDeviceClicked() {
showFragment(UnpairDeviceFragment.newInstance())
}

private fun showFragment(fragment: Fragment, showOnBack: Boolean = true) {
val fragmentTransaction = supportFragmentManager
.beginTransaction()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class SelectActionFragment : Fragment() {
clusterInteractionBtn.setOnClickListener { getCallback()?.handleClusterInteractionClicked() }
provisionCustomFlowBtn.setOnClickListener{ getCallback()?.handleCustomFlowClicked() }
wildcardBtn.setOnClickListener { getCallback()?.handleWildcardClicked() }
unpairDeviceBtn.setOnClickListener{ getCallback()?.handleUnpairDeviceClicked() }
}
}

Expand Down Expand Up @@ -157,6 +158,8 @@ class SelectActionFragment : Fragment() {
fun handleWildcardClicked()
/** Notifies listener of provision-custom-flow button click. */
fun handleCustomFlowClicked()
/** Notifies listener of unpair button click. */
fun handleUnpairDeviceClicked()
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.google.chip.chiptool.provisioning

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.UnpairDeviceCallback
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.clusterclient.AddressUpdateFragment
import kotlinx.android.synthetic.main.unpair_device_fragment.view.unpairDeviceBtn
import kotlinx.coroutines.*

class UnpairDeviceFragment : Fragment() {
private val deviceController: ChipDeviceController
get() = ChipClient.getDeviceController(requireContext())

private lateinit var scope: CoroutineScope

private lateinit var addressUpdateFragment: AddressUpdateFragment

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
scope = viewLifecycleOwner.lifecycleScope

return inflater.inflate(R.layout.unpair_device_fragment, container, false).apply {
addressUpdateFragment =
childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment

unpairDeviceBtn.setOnClickListener { scope.launch { unpairDeviceClick() } }
}
}

inner class ChipUnpairDeviceCallback : UnpairDeviceCallback {
override fun onError(status: Int, remoteDeviceId: Long) {
Log.d(TAG, "onError : $remoteDeviceId, $status")
}

override fun onSuccess(remoteDeviceId: Long) {
Log.d(TAG, "onSuccess : $remoteDeviceId")
}
}

private fun unpairDeviceClick() {
deviceController.unpairDeviceCallback(addressUpdateFragment.deviceId, ChipUnpairDeviceCallback())
}


companion object {
private const val TAG = "UnpairDeviceFragment"
fun newInstance(): UnpairDeviceFragment = UnpairDeviceFragment()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@
android:layout_marginTop="8dp"
android:text="@string/cluster_interaction_tool" />

<Button
android:id="@+id/unpairDeviceBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/unpair_device_btn_text" />

</LinearLayout>

</ScrollView>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.fragment.app.FragmentContainerView
android:id="@+id/addressUpdateFragment"
android:name="com.google.chip.chiptool.clusterclient.AddressUpdateFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

<Button
android:id="@+id/unpairDeviceBtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/unpair_device_btn_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/addressUpdateFragment"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,6 @@
<string name="select_a_cluster">Select a cluster</string>
<string name="endpoint_name">Endpoint: </string>
<string name="wifi_connect_btn_text">Connect</string>

<string name="unpair_device_btn_text">Unpair</string>
</resources>
22 changes: 19 additions & 3 deletions examples/chip-tool/commands/pairing/PairingCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,8 @@ CHIP_ERROR PairingCommand::PairWithMdns(NodeId remoteId)

CHIP_ERROR PairingCommand::Unpair(NodeId remoteId)
{
CHIP_ERROR err = CurrentCommissioner().UnpairDevice(remoteId);
SetCommandExitStatus(err);
return err;
mCurrentFabricRemover = Platform::MakeUnique<Controller::CurrentFabricRemover>(&CurrentCommissioner());
return mCurrentFabricRemover->RemoveCurrentFabric(remoteId, &mCurrentFabricRemoveCallback);
}

void PairingCommand::OnStatusUpdate(DevicePairingDelegate::Status status)
Expand Down Expand Up @@ -265,3 +264,20 @@ void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData &
SetCommandExitStatus(err);
}
}

void PairingCommand::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_ERROR err)
{
PairingCommand * command = reinterpret_cast<PairingCommand *>(context);
VerifyOrReturn(command != nullptr, ChipLogError(chipTool, "OnCurrentFabricRemove: context is null"));

if (err == CHIP_NO_ERROR)
{
ChipLogProgress(chipTool, "Device unpair completed with success: " ChipLogFormatX64, ChipLogValueX64(nodeId));
}
else
{
ChipLogProgress(chipTool, "Device unpair Failure: " ChipLogFormatX64 " %s", ChipLogValueX64(nodeId), ErrorStr(err));
}

command->SetCommandExitStatus(err);
}
10 changes: 9 additions & 1 deletion examples/chip-tool/commands/pairing/PairingCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "../common/CHIPCommand.h"
#include <controller/CommissioningDelegate.h>
#include <controller/CurrentFabricRemover.h>
#include <zap-generated/CHIPClusters.h>

#include <commands/common/CredentialIssuerCommands.h>
Expand Down Expand Up @@ -55,7 +56,8 @@ class PairingCommand : public CHIPCommand,
chip::Dnssd::DiscoveryFilterType filterType = chip::Dnssd::DiscoveryFilterType::kNone) :
CHIPCommand(commandName, credIssuerCmds),
mPairingMode(mode), mNetworkType(networkType),
mFilterType(filterType), mRemoteAddr{ IPAddress::Any, chip::Inet::InterfaceId::Null() }
mFilterType(filterType), mRemoteAddr{ IPAddress::Any, chip::Inet::InterfaceId::Null() },
mCurrentFabricRemoveCallback(OnCurrentFabricRemove, this)
{
AddArgument("node-id", 0, UINT64_MAX, &mNodeId);

Expand Down Expand Up @@ -184,4 +186,10 @@ class PairingCommand : public CHIPCommand,
char * mOnboardingPayload;
uint64_t mDiscoveryFilterCode;
char * mDiscoveryFilterInstanceName;

// For unpair
chip::Platform::UniquePtr<chip::Controller::CurrentFabricRemover> mCurrentFabricRemover;
chip::Callback::Callback<chip::Controller::OnCurrentFabricRemove> mCurrentFabricRemoveCallback;

static void OnCurrentFabricRemove(void * context, NodeId remoteNodeId, CHIP_ERROR status);
};
2 changes: 2 additions & 0 deletions src/controller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ static_library("controller") {
"CommissioningDelegate.cpp",
"CommissioningWindowOpener.cpp",
"CommissioningWindowOpener.h",
"CurrentFabricRemover.cpp",
"CurrentFabricRemover.h",
"DeviceDiscoveryDelegate.h",
"DevicePairingDelegate.h",
"EmptyDataModelHandler.cpp",
Expand Down
7 changes: 5 additions & 2 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <app/InteractionModelEngine.h>
#include <app/OperationalSessionSetup.h>
#include <app/util/error-mapping.h>
#include <controller/CurrentFabricRemover.h>
#include <credentials/CHIPCert.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <crypto/CHIPCryptoPAL.h>
Expand Down Expand Up @@ -894,8 +895,10 @@ CHIP_ERROR DeviceCommissioner::StopPairing(NodeId remoteDeviceId)

CHIP_ERROR DeviceCommissioner::UnpairDevice(NodeId remoteDeviceId)
{
// TODO: Send unpairing message to the remote device.
return CHIP_NO_ERROR;
MATTER_TRACE_EVENT_SCOPE("UnpairDevice", "DeviceCommissioner");
VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);

return AutoCurrentFabricRemover::RemoveCurrentFabric(this, remoteDeviceId);
}

void DeviceCommissioner::RendezvousCleanup(CHIP_ERROR status)
Expand Down
Loading