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

[Android] Implement remove ICD Client Info #33843

Merged
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 @@ -8,11 +8,13 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ChipICDClient
import chip.devicecontroller.UnpairDeviceCallback
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.clusterclient.AddressUpdateFragment
import com.google.chip.chiptool.databinding.UnpairDeviceFragmentBinding
import com.google.chip.chiptool.util.DeviceIdUtil
import kotlinx.coroutines.*

class UnpairDeviceFragment : Fragment() {
Expand Down Expand Up @@ -63,6 +65,18 @@ class UnpairDeviceFragment : Fragment() {
addressUpdateFragment.deviceId,
ChipUnpairDeviceCallback()
)

// Remove ICD Client info
if (addressUpdateFragment.isICDDevice()) {
ChipICDClient.clearICDClientInfo(deviceController.fabricIndex, addressUpdateFragment.deviceId)

Log.d(TAG, "ICDClientInfo : ${ChipICDClient.getICDClientInfo(deviceController.fabricIndex)}")
}
requireActivity().runOnUiThread {
Log.d(TAG, "remove : ${addressUpdateFragment.deviceId}")
DeviceIdUtil.removeCommissionedNodeId(requireContext(), addressUpdateFragment.deviceId)
addressUpdateFragment.updateDeviceIdSpinner()
}
}

companion object {
Expand Down
102 changes: 102 additions & 0 deletions src/controller/java/AndroidICDClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
#include "AndroidICDClient.h"

#include <app/icd/client/ICDClientInfo.h>
#include <lib/support/JniTypeWrappers.h>

chip::app::DefaultICDClientStorage sICDClientStorage;
static CHIP_ERROR ParseICDClientInfo(JNIEnv * env, jint jFabricIndex, jobject jIcdClientInfo,
chip::app::ICDClientInfo & icdClientInfo);

jobject getICDClientInfo(JNIEnv * env, const char * icdClientInfoSign, jint jFabricIndex)
{
Expand Down Expand Up @@ -93,6 +96,105 @@ jobject getICDClientInfo(JNIEnv * env, const char * icdClientInfoSign, jint jFab
return jInfo;
}

CHIP_ERROR StoreICDEntryWithKey(JNIEnv * env, jint jFabricIndex, jobject jicdClientInfo, jbyteArray jKey)
{
CHIP_ERROR err = CHIP_NO_ERROR;

chip::app::ICDClientInfo clientInfo;
chip::JniByteArray jniKey(env, jKey);

err = ParseICDClientInfo(env, jFabricIndex, jicdClientInfo, clientInfo);
VerifyOrReturnValue(err == CHIP_NO_ERROR, err,
ChipLogError(Controller, "Failed to parse ICD Client info: %" CHIP_ERROR_FORMAT, err.Format()));

err = getICDClientStorage()->SetKey(clientInfo, jniKey.byteSpan());

if (err == CHIP_NO_ERROR)
{
err = getICDClientStorage()->StoreEntry(clientInfo);
}
else
{
getICDClientStorage()->RemoveKey(clientInfo);
ChipLogError(Controller, "Failed to persist symmetric key with error: %" CHIP_ERROR_FORMAT, err.Format());
}

return err;
}

CHIP_ERROR RemoveICDEntryWithKey(JNIEnv * env, jint jFabricIndex, jobject jicdClientInfo)
{
CHIP_ERROR err = CHIP_NO_ERROR;

chip::app::ICDClientInfo info;
err = ParseICDClientInfo(env, jFabricIndex, jicdClientInfo, info);
VerifyOrReturnValue(err == CHIP_NO_ERROR, err,
ChipLogError(Controller, "Failed to parse ICD Client info: %" CHIP_ERROR_FORMAT, err.Format()));

getICDClientStorage()->RemoveKey(info);

return err;
}

CHIP_ERROR ClearICDClientInfo(JNIEnv * env, jint jFabricIndex, jlong jNodeId)
{
CHIP_ERROR err = CHIP_NO_ERROR;

chip::ScopedNodeId scopedNodeId(static_cast<chip::NodeId>(jNodeId), static_cast<chip::FabricIndex>(jFabricIndex));
err = getICDClientStorage()->DeleteEntry(scopedNodeId);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "ClearICDClientInfo error!: %" CHIP_ERROR_FORMAT, err.Format());
}
return err;
}

CHIP_ERROR ParseICDClientInfo(JNIEnv * env, jint jFabricIndex, jobject jIcdClientInfo, chip::app::ICDClientInfo & icdClientInfo)
{
VerifyOrReturnError(jIcdClientInfo != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

jmethodID getPeerNodeIdMethod = nullptr;
jmethodID getStartCounterMethod = nullptr;
jmethodID getOffsetMethod = nullptr;
jmethodID getMonitoredSubjectMethod = nullptr;
jmethodID getIcdAesKeyMethod = nullptr;
jmethodID getIcdHmacKeyMethod = nullptr;

ReturnErrorOnFailure(
chip::JniReferences::GetInstance().FindMethod(env, jIcdClientInfo, "getPeerNodeId", "()J", &getPeerNodeIdMethod));
ReturnErrorOnFailure(
chip::JniReferences::GetInstance().FindMethod(env, jIcdClientInfo, "getStartCounter", "()J", &getStartCounterMethod));
ReturnErrorOnFailure(chip::JniReferences::GetInstance().FindMethod(env, jIcdClientInfo, "getOffset", "()J", &getOffsetMethod));
ReturnErrorOnFailure(chip::JniReferences::GetInstance().FindMethod(env, jIcdClientInfo, "getMonitoredSubject", "()J",
&getMonitoredSubjectMethod));
ReturnErrorOnFailure(
chip::JniReferences::GetInstance().FindMethod(env, jIcdClientInfo, "getIcdAesKey", "()[B", &getIcdAesKeyMethod));
ReturnErrorOnFailure(
chip::JniReferences::GetInstance().FindMethod(env, jIcdClientInfo, "getIcdHmacKey", "()[B", &getIcdHmacKeyMethod));

jlong jPeerNodeId = env->CallLongMethod(jIcdClientInfo, getPeerNodeIdMethod);
jlong jStartCounter = env->CallLongMethod(jIcdClientInfo, getStartCounterMethod);
jlong jOffset = env->CallLongMethod(jIcdClientInfo, getOffsetMethod);
jlong jMonitoredSubject = env->CallLongMethod(jIcdClientInfo, getMonitoredSubjectMethod);
jbyteArray jIcdAesKey = static_cast<jbyteArray>(env->CallObjectMethod(jIcdClientInfo, getIcdAesKeyMethod));
jbyteArray jIcdHmacKey = static_cast<jbyteArray>(env->CallObjectMethod(jIcdClientInfo, getIcdHmacKeyMethod));

chip::ScopedNodeId scopedNodeId(static_cast<chip::NodeId>(jPeerNodeId), static_cast<chip::FabricIndex>(jFabricIndex));
chip::JniByteArray jniIcdAesKey(env, jIcdAesKey);
chip::JniByteArray jniIcdHmacKey(env, jIcdHmacKey);

icdClientInfo.peer_node = scopedNodeId;
icdClientInfo.start_icd_counter = static_cast<uint32_t>(jStartCounter);
icdClientInfo.offset = static_cast<uint32_t>(jOffset);
icdClientInfo.monitored_subject = static_cast<uint64_t>(jMonitoredSubject);
memcpy(icdClientInfo.aes_key_handle.AsMutable<chip::Crypto::Symmetric128BitsKeyByteArray>(), jniIcdAesKey.data(),
sizeof(chip::Crypto::Symmetric128BitsKeyByteArray));
memcpy(icdClientInfo.hmac_key_handle.AsMutable<chip::Crypto::Symmetric128BitsKeyByteArray>(), jniIcdHmacKey.data(),
sizeof(chip::Crypto::Symmetric128BitsKeyByteArray));

return CHIP_NO_ERROR;
}

chip::app::DefaultICDClientStorage * getICDClientStorage()
{
return &sICDClientStorage;
Expand Down
6 changes: 6 additions & 0 deletions src/controller/java/AndroidICDClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@

jobject getICDClientInfo(JNIEnv * env, const char * icdClientInfoSign, jint jFabricIndex);

CHIP_ERROR StoreICDEntryWithKey(JNIEnv * env, jint jFabricIndex, jobject jicdClientInfo, jbyteArray jKey);

CHIP_ERROR RemoveICDEntryWithKey(JNIEnv * env, jint jFabricIndex, jobject jicdClientInfo);

CHIP_ERROR ClearICDClientInfo(JNIEnv * env, jint jFabricIndex, jlong jNodeId);

chip::app::DefaultICDClientStorage * getICDClientStorage();
18 changes: 18 additions & 0 deletions src/controller/java/CHIPICDClient-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,21 @@ JNI_METHOD(jobject, getICDClientInfo)(JNIEnv * env, jobject self, jint jFabricIn

return getICDClientInfo(env, "chip/devicecontroller/ICDClientInfo", jFabricIndex);
}

JNI_METHOD(void, storeICDEntryWithKey)(JNIEnv * env, jobject self, jint jFabricIndex, jobject jicdClientInfo, jbyteArray jKey)
{
chip::DeviceLayer::StackLock lock;
StoreICDEntryWithKey(env, jFabricIndex, jicdClientInfo, jKey);
}

JNI_METHOD(void, removeICDEntryWithKey)(JNIEnv * env, jobject self, jint jFabricIndex, jobject jicdClientInfo)
{
chip::DeviceLayer::StackLock lock;
RemoveICDEntryWithKey(env, jFabricIndex, jicdClientInfo);
}

JNI_METHOD(void, clearICDClientInfo)(JNIEnv * env, jobject self, jint jFabricIndex, jlong jNodeId)
{
chip::DeviceLayer::StackLock lock;
ClearICDClientInfo(env, jFabricIndex, jNodeId);
}
18 changes: 18 additions & 0 deletions src/controller/java/MatterICDClient-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,21 @@ JNI_METHOD(jobject, getICDClientInfo)(JNIEnv * env, jobject self, jint jFabricIn

return getICDClientInfo(env, "matter/controller/ICDClientInfo", jFabricIndex);
}

JNI_METHOD(void, storeICDEntryWithKey)(JNIEnv * env, jobject self, jint jFabricIndex, jobject jicdClientInfo, jbyteArray jKey)
{
chip::DeviceLayer::StackLock lock;
StoreICDEntryWithKey(env, jFabricIndex, jicdClientInfo, jKey);
}

JNI_METHOD(void, removeICDEntryWithKey)(JNIEnv * env, jobject self, jint jFabricIndex, jobject jicdClientInfo)
{
chip::DeviceLayer::StackLock lock;
RemoveICDEntryWithKey(env, jFabricIndex, jicdClientInfo);
}

JNI_METHOD(void, clearICDClientInfo)(JNIEnv * env, jobject self, jint jFabricIndex, jlong jNodeId)
{
chip::DeviceLayer::StackLock lock;
ClearICDClientInfo(env, jFabricIndex, jNodeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,12 @@ public static boolean isPeerICDClient(int fabricIndex, long deviceId) {
return clientInfo.stream().anyMatch(info -> info.getPeerNodeId() == deviceId);
}

public static native void storeICDEntryWithKey(
int fabricIndex, ICDClientInfo icdClientInfo, byte[] key);

public static native void removeICDEntryWithKey(int fabricIndex, ICDClientInfo icdClientInfo);

public static native void clearICDClientInfo(int fabricIndex, long deviceId);

public static native List<ICDClientInfo> getICDClientInfo(int fabricIndex);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ object MatterICDClientImpl {
return clientInfo.firstOrNull { it.peerNodeId == deviceId } != null
}

external fun storeICDEntryWithKey(fabricIndex: Int, icdClientInfo: ICDClientInfo, key: ByteArray)

external fun removeICDEntryWithKey(fabricIndex: Int, icdClientInfo: ICDClientInfo)

external fun clearICDClientInfo(fabricIndex: Int, deviceId: Long)

external fun getICDClientInfo(fabricIndex: Int): List<ICDClientInfo>?
}
Loading