Skip to content

Commit 6484d4d

Browse files
[Android] Implement for supporting ICD device (project-chip#31055)
* Implement for supporting ICD device in Android Controller * Add exception TooManyFunctions * Restyled by google-java-format * Restyled by clang-format * Add comment * Modify typo, use static_cast * Modify comments * Add default parameter for ICD * Add java test for ICD * Remove 'p' * Restyled by google-java-format * Update comment * Restyled by google-java-format --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 0aa3a0c commit 6484d4d

File tree

14 files changed

+452
-12
lines changed

14 files changed

+452
-12
lines changed

.github/workflows/java-tests.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ jobs:
9090
"./scripts/build/build_examples.py \
9191
--target linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test \
9292
--target linux-x64-java-matter-controller \
93+
--target linux-x64-lit-icd-ipv6only \
9394
build \
9495
"
9596
- name: Build Kotlin Matter Controller
@@ -210,6 +211,17 @@ jobs:
210211
--tool-args "code --nodeid 1 --setup-payload 34970112332 --discover-once 1 --use-only-onnetwork-discovery 0 -t 1000" \
211212
--factoryreset \
212213
'
214+
- name: Run Pairing ICD Onnetwork Test
215+
run: |
216+
scripts/run_in_python_env.sh out/venv \
217+
'./scripts/tests/run_java_test.py \
218+
--app out/linux-x64-lit-icd-ipv6only/lit-icd-app \
219+
--app-args "--discriminator 3840 --interface-id -1" \
220+
--tool-path out/linux-x64-java-matter-controller \
221+
--tool-cluster "pairing" \
222+
--tool-args "onnetwork-long --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \
223+
--factoryreset \
224+
'
213225
- name: Run Pairing Onnetwork Test
214226
run: |
215227
scripts/run_in_python_env.sh out/venv \

examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt

+8
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,12 @@ open class GenericChipDeviceListener : ChipDeviceController.CompletionListener {
5151
override fun onOpCSRGenerationComplete(csr: ByteArray) {
5252
// No op
5353
}
54+
55+
override fun onICDRegistrationInfoRequired() {
56+
// No op
57+
}
58+
59+
override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) {
60+
// No op
61+
}
5462
}

examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt

+12
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.lifecycle.lifecycleScope
3232
import chip.devicecontroller.AttestationInfo
3333
import chip.devicecontroller.ChipDeviceController
3434
import chip.devicecontroller.DeviceAttestationDelegate
35+
import chip.devicecontroller.ICDRegistrationInfo
3536
import chip.devicecontroller.NetworkCredentials
3637
import com.google.chip.chiptool.ChipClient
3738
import com.google.chip.chiptool.GenericChipDeviceListener
@@ -284,6 +285,17 @@ class DeviceProvisioningFragment : Fragment() {
284285
override fun onError(error: Throwable?) {
285286
Log.d(TAG, "onError: $error")
286287
}
288+
289+
override fun onICDRegistrationInfoRequired() {
290+
Log.d(TAG, "onICDRegistrationInfoRequired")
291+
deviceController.updateCommissioningICDRegistrationInfo(
292+
ICDRegistrationInfo.newBuilder().build()
293+
)
294+
}
295+
296+
override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) {
297+
Log.d(TAG, "onICDRegistrationComplete - icdNodeId : $icdNodeId, icdCounter : $icdCounter")
298+
}
287299
}
288300

289301
/** Callback from [DeviceProvisioningFragment] notifying any registered listeners. */

examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt

+14
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.matter.controller.commands.pairing
1919

2020
import chip.devicecontroller.ChipDeviceController
21+
import chip.devicecontroller.ICDRegistrationInfo
2122
import chip.devicecontroller.NetworkCredentials
2223
import com.matter.controller.commands.common.CredentialsIssuer
2324
import com.matter.controller.commands.common.IPAddress
@@ -178,6 +179,19 @@ abstract class PairingCommand(
178179
}
179180
}
180181

182+
override fun onICDRegistrationInfoRequired() {
183+
logger.log(Level.INFO, "onICDRegistrationInfoRequired")
184+
currentCommissioner()
185+
.updateCommissioningICDRegistrationInfo(ICDRegistrationInfo.newBuilder().build())
186+
}
187+
188+
override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) {
189+
logger.log(
190+
Level.INFO,
191+
"onICDRegistrationComplete with icdNodeId: $icdNodeId, icdCounter: $icdCounter"
192+
)
193+
}
194+
181195
fun getNodeId(): Long {
182196
return nodeId.get()
183197
}

examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt

+11
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,17 @@ abstract class PairingCommand(
173173
}
174174
}
175175

176+
override fun onICDRegistrationInfoRequired() {
177+
logger.log(Level.INFO, "onICDRegistrationInfoRequired")
178+
}
179+
180+
override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) {
181+
logger.log(
182+
Level.INFO,
183+
"onICDRegistrationComplete with icdNodeId: $icdNodeId, icdCounter: $icdCounter"
184+
)
185+
}
186+
176187
fun getNodeId(): Long {
177188
return nodeId.get()
178189
}

kotlin-detect-config.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ complexity:
300300
- "**/src/controller/java/src/matter/tlv/TlvWriter.kt"
301301
- "**/src/controller/java/src/matter/controller/MatterControllerImpl.kt"
302302
- "**/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt"
303+
- "**/src/controller/java/src/matter/controller/MatterController.kt"
303304
- "**/src/controller/java/tests/matter/jsontlv/JsonToTlvToJsonTest.kt"
304305
- "**/src/controller/java/tests/matter/onboardingpayload/ManualCodeTest.kt"
305306
- "**/src/controller/java/tests/matter/onboardingpayload/QRCodeTest.kt"

src/controller/java/AndroidDeviceControllerWrapper.cpp

+85
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,66 @@ CHIP_ERROR AndroidDeviceControllerWrapper::ApplyNetworkCredentials(chip::Control
444444
return err;
445445
}
446446

447+
CHIP_ERROR AndroidDeviceControllerWrapper::ApplyICDRegistrationInfo(chip::Controller::CommissioningParameters & params,
448+
jobject icdRegistrationInfo)
449+
{
450+
chip::DeviceLayer::StackUnlock unlock;
451+
CHIP_ERROR err = CHIP_NO_ERROR;
452+
453+
VerifyOrReturnError(icdRegistrationInfo != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
454+
455+
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
456+
jmethodID getCheckInNodeIdMethod;
457+
err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getCheckInNodeId", "()Ljava/lang/Long;",
458+
&getCheckInNodeIdMethod);
459+
VerifyOrReturnError(err == CHIP_NO_ERROR, err);
460+
jobject jCheckInNodeId = env->CallObjectMethod(icdRegistrationInfo, getCheckInNodeIdMethod);
461+
462+
jmethodID getMonitoredSubjectMethod;
463+
err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getMonitoredSubject", "()Ljava/lang/Long;",
464+
&getMonitoredSubjectMethod);
465+
VerifyOrReturnError(err == CHIP_NO_ERROR, err);
466+
jobject jMonitoredSubject = env->CallObjectMethod(icdRegistrationInfo, getMonitoredSubjectMethod);
467+
468+
jmethodID getSymmetricKeyMethod;
469+
err =
470+
chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getSymmetricKey", "()[B", &getSymmetricKeyMethod);
471+
VerifyOrReturnError(err == CHIP_NO_ERROR, err);
472+
jbyteArray jSymmetricKey = static_cast<jbyteArray>(env->CallObjectMethod(icdRegistrationInfo, getSymmetricKeyMethod));
473+
474+
chip::NodeId checkInNodeId = chip::kUndefinedNodeId;
475+
if (jCheckInNodeId != nullptr)
476+
{
477+
checkInNodeId = static_cast<chip::NodeId>(chip::JniReferences::GetInstance().LongToPrimitive(jCheckInNodeId));
478+
}
479+
else
480+
{
481+
checkInNodeId = mController->GetNodeId();
482+
}
483+
params.SetICDCheckInNodeId(checkInNodeId);
484+
485+
uint64_t monitoredSubject = static_cast<uint64_t>(checkInNodeId);
486+
if (jMonitoredSubject != nullptr)
487+
{
488+
monitoredSubject = static_cast<uint64_t>(chip::JniReferences::GetInstance().LongToPrimitive(jMonitoredSubject));
489+
}
490+
params.SetICDMonitoredSubject(monitoredSubject);
491+
492+
if (jSymmetricKey != nullptr)
493+
{
494+
JniByteArray jniSymmetricKey(env, jSymmetricKey);
495+
VerifyOrReturnError(jniSymmetricKey.size() == sizeof(mICDSymmetricKey), CHIP_ERROR_INVALID_ARGUMENT);
496+
memcpy(mICDSymmetricKey, jniSymmetricKey.data(), sizeof(mICDSymmetricKey));
497+
}
498+
else
499+
{
500+
chip::Crypto::DRBG_get_bytes(mICDSymmetricKey, sizeof(mICDSymmetricKey));
501+
}
502+
params.SetICDSymmetricKey(chip::ByteSpan(mICDSymmetricKey));
503+
504+
return err;
505+
}
506+
447507
CHIP_ERROR AndroidDeviceControllerWrapper::UpdateCommissioningParameters(const chip::Controller::CommissioningParameters & params)
448508
{
449509
// this will wipe out any custom attestationNonce and csrNonce that was being used.
@@ -814,6 +874,31 @@ void AndroidDeviceControllerWrapper::OnScanNetworksFailure(CHIP_ERROR error)
814874
CallJavaMethod("onScanNetworksFailure", static_cast<jint>(error.AsInteger()));
815875
}
816876

877+
void AndroidDeviceControllerWrapper::OnICDRegistrationInfoRequired()
878+
{
879+
chip::DeviceLayer::StackUnlock unlock;
880+
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
881+
jmethodID onICDRegistrationInfoRequiredMethod;
882+
CHIP_ERROR err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onICDRegistrationInfoRequired", "()V",
883+
&onICDRegistrationInfoRequiredMethod);
884+
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format()));
885+
886+
env->CallVoidMethod(mJavaObjectRef, onICDRegistrationInfoRequiredMethod);
887+
}
888+
889+
void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter)
890+
{
891+
chip::DeviceLayer::StackUnlock unlock;
892+
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
893+
jmethodID onICDRegistrationCompleteMethod;
894+
CHIP_ERROR err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onICDRegistrationComplete", "(JJ)V",
895+
&onICDRegistrationCompleteMethod);
896+
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format()));
897+
898+
env->CallVoidMethod(mJavaObjectRef, onICDRegistrationCompleteMethod, static_cast<jlong>(icdNodeId),
899+
static_cast<jlong>(icdCounter));
900+
}
901+
817902
CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, void * value, uint16_t & size)
818903
{
819904
ChipLogProgress(chipTool, "KVS: Getting key %s", StringOrNullMarker(key));

src/controller/java/AndroidDeviceControllerWrapper.h

+8
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel
8787
*/
8888
CHIP_ERROR ApplyNetworkCredentials(chip::Controller::CommissioningParameters & params, jobject networkCredentials);
8989

90+
/**
91+
* Convert ICD Registration Infomations from Java, and apply them to the commissioning parameters object.
92+
*/
93+
CHIP_ERROR ApplyICDRegistrationInfo(chip::Controller::CommissioningParameters & params, jobject icdRegistrationInfo);
94+
9095
/**
9196
* Update the CommissioningParameters used by the active device commissioner
9297
*/
@@ -103,6 +108,8 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel
103108
void OnScanNetworksSuccess(
104109
const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & dataResponse) override;
105110
void OnScanNetworksFailure(CHIP_ERROR error) override;
111+
void OnICDRegistrationInfoRequired() override;
112+
void OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter) override;
106113

107114
// PersistentStorageDelegate implementation
108115
CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override;
@@ -242,6 +249,7 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel
242249
#if CHIP_DEVICE_CONFIG_DYNAMIC_SERVER
243250
OTAProviderDelegateBridge * mOtaProviderBridge = nullptr;
244251
#endif
252+
uint8_t mICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length];
245253

246254
AndroidDeviceControllerWrapper(ChipDeviceControllerPtr controller,
247255
#ifdef JAVA_MATTER_CONTROLLER_TEST

src/controller/java/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ android_library("java") {
444444
"src/chip/devicecontroller/DiscoveredDevice.java",
445445
"src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java",
446446
"src/chip/devicecontroller/GroupKeySecurityPolicy.java",
447+
"src/chip/devicecontroller/ICDRegistrationInfo.java",
447448
"src/chip/devicecontroller/InvokeCallback.java",
448449
"src/chip/devicecontroller/InvokeCallbackJni.java",
449450
"src/chip/devicecontroller/KeypairDelegate.java",

src/controller/java/CHIPDeviceController-JNI.cpp

+58-3
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ JNI_METHOD(void, commissionDevice)
627627

628628
JNI_METHOD(void, pairDevice)
629629
(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jint connObj, jlong pinCode, jbyteArray csrNonce,
630-
jobject networkCredentials)
630+
jobject networkCredentials, jobject icdRegistrationInfo)
631631
{
632632
chip::DeviceLayer::StackLock lock;
633633
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -656,6 +656,13 @@ JNI_METHOD(void, pairDevice)
656656
JniByteArray jniCsrNonce(env, csrNonce);
657657
commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan());
658658
}
659+
660+
commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete);
661+
if (icdRegistrationInfo != nullptr)
662+
{
663+
wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo);
664+
}
665+
659666
if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr)
660667
{
661668
commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge());
@@ -671,7 +678,7 @@ JNI_METHOD(void, pairDevice)
671678

672679
JNI_METHOD(void, pairDeviceWithAddress)
673680
(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jstring address, jint port, jint discriminator, jlong pinCode,
674-
jbyteArray csrNonce)
681+
jbyteArray csrNonce, jobject icdRegistrationInfo)
675682
{
676683
chip::DeviceLayer::StackLock lock;
677684
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -699,6 +706,13 @@ JNI_METHOD(void, pairDeviceWithAddress)
699706
JniByteArray jniCsrNonce(env, csrNonce);
700707
commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan());
701708
}
709+
710+
commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete);
711+
if (icdRegistrationInfo != nullptr)
712+
{
713+
wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo);
714+
}
715+
702716
if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr)
703717
{
704718
commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge());
@@ -714,7 +728,7 @@ JNI_METHOD(void, pairDeviceWithAddress)
714728

715729
JNI_METHOD(void, pairDeviceWithCode)
716730
(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jstring setUpCode, jboolean discoverOnce,
717-
jboolean useOnlyOnNetworkDiscovery, jbyteArray csrNonce, jobject networkCredentials)
731+
jboolean useOnlyOnNetworkDiscovery, jbyteArray csrNonce, jobject networkCredentials, jobject icdRegistrationInfo)
718732
{
719733
chip::DeviceLayer::StackLock lock;
720734
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -748,6 +762,12 @@ JNI_METHOD(void, pairDeviceWithCode)
748762
wrapper->ApplyNetworkCredentials(commissioningParams, networkCredentials);
749763
}
750764

765+
commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete);
766+
if (icdRegistrationInfo != nullptr)
767+
{
768+
wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo);
769+
}
770+
751771
if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr)
752772
{
753773
commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge());
@@ -899,6 +919,41 @@ JNI_METHOD(void, updateCommissioningNetworkCredentials)
899919
}
900920
}
901921

922+
JNI_METHOD(void, updateCommissioningICDRegistrationInfo)
923+
(JNIEnv * env, jobject self, jlong handle, jobject icdRegistrationInfo)
924+
{
925+
ChipLogProgress(Controller, "updateCommissioningICDRegistrationInfo() called");
926+
chip::DeviceLayer::StackLock lock;
927+
AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle);
928+
929+
CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters();
930+
CHIP_ERROR err = wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo);
931+
if (err != CHIP_NO_ERROR)
932+
{
933+
ChipLogError(Controller, "ApplyICDRegistrationInfo failed. Err = %" CHIP_ERROR_FORMAT, err.Format());
934+
JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err);
935+
return;
936+
}
937+
err = wrapper->UpdateCommissioningParameters(commissioningParams);
938+
if (err != CHIP_NO_ERROR)
939+
{
940+
ChipLogError(Controller, "UpdateCommissioningParameters failed. Err = %" CHIP_ERROR_FORMAT, err.Format());
941+
JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err);
942+
return;
943+
}
944+
945+
// Only invoke ICDRegistrationInfoReady when called in ICDRegistartionInfo stage.
946+
if (wrapper->Controller()->GetCommissioningStage() == CommissioningStage::kICDGetRegistrationInfo)
947+
{
948+
err = wrapper->Controller()->ICDRegistrationInfoReady();
949+
if (err != CHIP_NO_ERROR)
950+
{
951+
ChipLogError(Controller, "ICDRegistrationInfoReady failed. Err = %" CHIP_ERROR_FORMAT, err.Format());
952+
JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err);
953+
}
954+
}
955+
}
956+
902957
jint GetCalendarFieldID(JNIEnv * env, const char * method)
903958
{
904959
jclass calendarCls = env->FindClass("java/util/Calendar");

0 commit comments

Comments
 (0)