diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt index e4542fc518e9a8..2d126e31c6c426 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt @@ -57,12 +57,7 @@ open class GenericChipDeviceListener : ChipDeviceController.CompletionListener { // No op } - override fun onICDRegistrationComplete( - errorCode: Int, - icdNodeId: Long, - icdCounter: Long, - icdDeviceInfo: ICDDeviceInfo - ) { + override fun onICDRegistrationComplete(errorCode: Int, icdDeviceInfo: ICDDeviceInfo) { // No op } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt index 88c9965d31f658..991a1f58311e55 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt @@ -294,16 +294,22 @@ class DeviceProvisioningFragment : Fragment() { ) } - override fun onICDRegistrationComplete( - errorCode: Int, - icdNodeId: Long, - icdCounter: Long, - icdDeviceInfo: ICDDeviceInfo - ) { + override fun onICDRegistrationComplete(errorCode: Int, icdDeviceInfo: ICDDeviceInfo) { Log.d( TAG, - "onICDRegistrationComplete - errorCode: $errorCode, icdNodeId : $icdNodeId, icdCounter : $icdCounter, symmetricKey : ${icdDeviceInfo.symmetricKey.toHex()}" + "onICDRegistrationComplete - errorCode: $errorCode, symmetricKey : ${icdDeviceInfo.symmetricKey.toHex()}, icdDeviceInfo : $icdDeviceInfo" ) + requireActivity().runOnUiThread { + Toast.makeText( + requireActivity(), + getString( + R.string.icd_registration_completed, + icdDeviceInfo.userActiveModeTriggerHint.toString() + ), + Toast.LENGTH_LONG + ) + .show() + } } } diff --git a/examples/android/CHIPTool/app/src/main/res/values/strings.xml b/examples/android/CHIPTool/app/src/main/res/values/strings.xml index 0737ba3be27b62..62e0b428135f36 100644 --- a/examples/android/CHIPTool/app/src/main/res/values/strings.xml +++ b/examples/android/CHIPTool/app/src/main/res/values/strings.xml @@ -276,4 +276,5 @@ Node ID Intermittently Connected Device + ICD device registration completed, How to trigger to switch to Active Mode : %1$s diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt index 8ba8fddfa501d5..dab53e3913c28f 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt @@ -186,15 +186,10 @@ abstract class PairingCommand( .updateCommissioningICDRegistrationInfo(ICDRegistrationInfo.newBuilder().build()) } - override fun onICDRegistrationComplete( - errorCode: Int, - icdNodeId: Long, - icdCounter: Long, - icdDeviceInfo: ICDDeviceInfo - ) { + override fun onICDRegistrationComplete(errorCode: Int, icdDeviceInfo: ICDDeviceInfo) { logger.log( Level.INFO, - "onICDRegistrationComplete with errorCode: $errorCode, icdNodeId: $icdNodeId, icdCounter: $icdCounter, symmetricKey: ${icdDeviceInfo.symmetricKey.toHex()}" + "onICDRegistrationComplete with errorCode: $errorCode, symmetricKey: ${icdDeviceInfo.symmetricKey.toHex()}, icdDeviceInfo: $icdDeviceInfo" ) } diff --git a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt index 712ad374ced579..c896e0b88f46a6 100644 --- a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt +++ b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt @@ -178,15 +178,10 @@ abstract class PairingCommand( logger.log(Level.INFO, "onICDRegistrationInfoRequired") } - override fun onICDRegistrationComplete( - errorCode: Int, - icdNodeId: Long, - icdCounter: Long, - icdDeviceInfo: ICDDeviceInfo - ) { + override fun onICDRegistrationComplete(errorCode: Int, icdDeviceInfo: ICDDeviceInfo) { logger.log( Level.INFO, - "onICDRegistrationComplete with errorCode: $errorCode, icdNodeId: $icdNodeId, icdCounter: $icdCounter, symmetricKey: ${icdDeviceInfo.symmetricKey.toHex()}" + "onICDRegistrationComplete with errorCode: $errorCode, symmetricKey: ${icdDeviceInfo.symmetricKey.toHex()}, icdDeviceInfo: $icdDeviceInfo" ) } diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 93be8209ee4029..39feef3f704177 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -713,6 +713,10 @@ void AndroidDeviceControllerWrapper::OnReadCommissioningInfo(const chip::Control &onReadCommissioningInfoMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format())); + // For ICD + mUserActiveModeTriggerHint = info.icd.userActiveModeTriggerHint; + CopyCharSpanToMutableCharSpan(info.icd.userActiveModeTriggerInstruction, mUserActiveModeTriggerInstruction); + env->CallVoidMethod(mJavaObjectRef, onReadCommissioningInfoMethod, static_cast(info.basic.vendorId), static_cast(info.basic.productId), static_cast(info.network.wifi.endpoint), static_cast(info.network.thread.endpoint)); @@ -939,6 +943,8 @@ void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdN mDeviceIsICD = true; JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + + JniLocalReferenceManager manager(env); jmethodID onICDRegistrationCompleteMethod; jclass icdDeviceInfoClass = nullptr; jmethodID icdDeviceInfoStructCtor = nullptr; @@ -946,14 +952,14 @@ void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdN jbyteArray jSymmetricKey = nullptr; CHIP_ERROR methodErr = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onICDRegistrationComplete", - "(IJJLchip/devicecontroller/ICDDeviceInfo;)V", &onICDRegistrationCompleteMethod); + "(ILchip/devicecontroller/ICDDeviceInfo;)V", &onICDRegistrationCompleteMethod); VerifyOrReturn(methodErr == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, methodErr.Format())); - methodErr = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ICDDeviceInfo", icdDeviceInfoClass); + methodErr = chip::JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/ICDDeviceInfo", icdDeviceInfoClass); VerifyOrReturn(methodErr == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find class ICDDeviceInfo")); - icdDeviceInfoStructCtor = env->GetMethodID(icdDeviceInfoClass, "", "([B)V"); + icdDeviceInfoStructCtor = env->GetMethodID(icdDeviceInfoClass, "", "([BILjava/lang/String;JJJJI)V"); VerifyOrReturn(icdDeviceInfoStructCtor != nullptr, ChipLogError(Controller, "Could not find ICDDeviceInfo constructor")); methodErr = @@ -961,10 +967,15 @@ void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdN VerifyOrReturn(methodErr == CHIP_NO_ERROR, ChipLogError(Controller, "Error Parsing Symmetric Key: %" CHIP_ERROR_FORMAT, methodErr.Format())); - icdDeviceInfoObj = env->NewObject(icdDeviceInfoClass, icdDeviceInfoStructCtor, jSymmetricKey); + jstring jUserActiveModeTriggerInstruction = env->NewStringUTF(mUserActiveModeTriggerInstruction.data()); + + icdDeviceInfoObj = env->NewObject( + icdDeviceInfoClass, icdDeviceInfoStructCtor, jSymmetricKey, static_cast(mUserActiveModeTriggerHint.Raw()), + jUserActiveModeTriggerInstruction, static_cast(icdNodeId), static_cast(icdCounter), + static_cast(mAutoCommissioner.GetCommissioningParameters().GetICDMonitoredSubject().Value()), + static_cast(Controller()->GetFabricId()), static_cast(Controller()->GetFabricIndex())); - env->CallVoidMethod(mJavaObjectRef, onICDRegistrationCompleteMethod, static_cast(err.AsInteger()), - static_cast(icdNodeId), static_cast(icdCounter), icdDeviceInfoObj); + env->CallVoidMethod(mJavaObjectRef, onICDRegistrationCompleteMethod, static_cast(err.AsInteger()), icdDeviceInfoObj); } CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, void * value, uint16_t & size) diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index 982609376e9319..4e9a541fa29564 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -48,6 +48,8 @@ #include "OTAProviderDelegateBridge.h" #endif +constexpr uint8_t kUserActiveModeTriggerInstructionBufferLen = + 128 + 1; // 128bytes is max UserActiveModeTriggerInstruction size and 1 byte is for escape sequence. /** * This class contains all relevant information for the JNI view of CHIPDeviceController * to handle all controller-related processing. @@ -256,6 +258,9 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel #endif bool mDeviceIsICD = false; uint8_t mICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; + char mUserActiveModeTriggerInstructionBuffer[kUserActiveModeTriggerInstructionBufferLen]; + chip::MutableCharSpan mUserActiveModeTriggerInstruction = chip::MutableCharSpan(mUserActiveModeTriggerInstructionBuffer); + chip::BitMask mUserActiveModeTriggerHint; AndroidDeviceControllerWrapper(ChipDeviceControllerPtr controller, #ifdef JAVA_MATTER_CONTROLLER_TEST diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 454b0df3a8a5f4..817a88c7d883ee 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -606,10 +606,9 @@ public void onICDRegistrationInfoRequired() { } } - public void onICDRegistrationComplete( - int errorCode, long icdNodeId, long icdCounter, ICDDeviceInfo icdDeviceInfo) { + public void onICDRegistrationComplete(int errorCode, ICDDeviceInfo icdDeviceInfo) { if (completionListener != null) { - completionListener.onICDRegistrationComplete(errorCode, icdNodeId, icdCounter, icdDeviceInfo); + completionListener.onICDRegistrationComplete(errorCode, icdDeviceInfo); } } @@ -1621,7 +1620,6 @@ void onReadCommissioningInfo( void onICDRegistrationInfoRequired(); /** Notifies when the registration flow for the ICD completes. */ - void onICDRegistrationComplete( - int errorCode, long icdNodeId, long icdCounter, ICDDeviceInfo icdDeviceInfo); + void onICDRegistrationComplete(int errorCode, ICDDeviceInfo icdDeviceInfo); } } diff --git a/src/controller/java/src/chip/devicecontroller/ICDDeviceInfo.java b/src/controller/java/src/chip/devicecontroller/ICDDeviceInfo.java index a6d4666df9270b..5d55e8cf291594 100644 --- a/src/controller/java/src/chip/devicecontroller/ICDDeviceInfo.java +++ b/src/controller/java/src/chip/devicecontroller/ICDDeviceInfo.java @@ -17,16 +17,153 @@ */ package chip.devicecontroller; +import java.util.HashSet; +import java.util.Set; + /** Class for holding ICD Device information. */ public class ICDDeviceInfo { - private byte[] symmetricKey; + /** List of methods to trigger the ICD to switch to Active mode. */ + public enum UserActiveModeTriggerBitmap { + PowerCycle(0), + SettingsMenu(1), + CustomInstruction(2), + DeviceManual(3), + ActuateSensor(4), + ActuateSensorSeconds(5), + ActuateSensorTimes(6), + ActuateSensorLightsBlink(7), + ResetButton(8), + ResetButtonLightsBlink(9), + ResetButtonSeconds(10), + ResetButtonTimes(11), + SetupButton(12), + SetupButtonSeconds(13), + SetupButtonLightsBlink(14), + SetupButtonTimes(15), + AppDefinedButton(16); + + private final int bitIndex; - public ICDDeviceInfo(byte[] symmetricKey) { + UserActiveModeTriggerBitmap(int bitIndex) { + this.bitIndex = bitIndex; + } + + public int getBitIndex() { + return bitIndex; + } + } + + private final byte[] symmetricKey; + private final Set userActiveModeTriggerHint; + private final String userActiveModeTriggerInstruction; + private final long icdNodeId; + private final long icdCounter; + private final long monitoredSubject; + private final long fabricId; + private final int fabricIndex; + + ICDDeviceInfo( + byte[] symmetricKey, + Set userActiveModeTriggerHint, + String userActiveModeTriggerInstruction, + long icdNodeId, + long icdCounter, + long monitoredSubject, + long fabricId, + int fabricIndex) { this.symmetricKey = symmetricKey; + this.userActiveModeTriggerHint = userActiveModeTriggerHint; + this.userActiveModeTriggerInstruction = userActiveModeTriggerInstruction; + this.icdNodeId = icdNodeId; + this.icdCounter = icdCounter; + this.monitoredSubject = monitoredSubject; + this.fabricId = fabricId; + this.fabricIndex = fabricIndex; + } + + ICDDeviceInfo( + byte[] symmetricKey, + int userActiveModeTriggerHintRaw, + String userActiveModeTriggerInstruction, + long icdNodeId, + long icdCounter, + long monitoredSubject, + long fabricId, + int fabricIndex) { + this.symmetricKey = symmetricKey; + this.userActiveModeTriggerInstruction = userActiveModeTriggerInstruction; + this.icdNodeId = icdNodeId; + this.icdCounter = icdCounter; + this.monitoredSubject = monitoredSubject; + this.fabricId = fabricId; + this.fabricIndex = fabricIndex; + + this.userActiveModeTriggerHint = new HashSet<>(); + for (UserActiveModeTriggerBitmap mode : UserActiveModeTriggerBitmap.values()) { + int bitmask = 1 << mode.getBitIndex(); + if ((userActiveModeTriggerHintRaw & bitmask) != 0) { + userActiveModeTriggerHint.add(mode); + } + } } /** Returns the 16 bytes ICD symmetric key. */ public byte[] getSymmetricKey() { return symmetricKey; } + + /** Returns the Set of UserActiveModeTriggerHint. */ + public Set getUserActiveModeTriggerHint() { + return userActiveModeTriggerHint; + } + + /** Returns the UserActiveModeTriggerInstruction. */ + public String getUserActiveModeTriggerInstruction() { + return userActiveModeTriggerInstruction; + } + + /** Returns the ICD Node Id. */ + public long getIcdNodeId() { + return icdNodeId; + } + + /** Returns the ICD Counter. */ + public long getIcdCounter() { + return icdCounter; + } + + /** Returns the Monitored Subject. */ + public long getMonitoredSubject() { + return monitoredSubject; + } + + /** Returns the Fabric Id */ + public long getFabricId() { + return fabricId; + } + + /** Returns the Fabric Index */ + public int getFabricIndex() { + return fabricIndex; + } + + @Override + public String toString() { + return "ICDDeviceInfo : {" + + "\n\tuserActiveModeTriggerHint : " + + userActiveModeTriggerHint + + "\n\tuserActiveModeTriggerInstruction : " + + userActiveModeTriggerInstruction + + "\n\ticdNodeId : " + + icdNodeId + + "\n\ticdCounter : " + + icdCounter + + "\n\tmonitoredSubject : " + + monitoredSubject + + "\n\tfabricId : " + + fabricId + + "\n\tfabricIndex : " + + fabricIndex + + "\n}"; + } } diff --git a/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt b/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt index 71352075e0e912..148fd71594f70a 100644 --- a/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt +++ b/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt @@ -52,12 +52,8 @@ class CompletionListenerAdapter(val listener: MatterController.CompletionListene override fun onICDRegistrationInfoRequired() = listener.onICDRegistrationInfoRequired() - override fun onICDRegistrationComplete( - errorCode: Int, - icdNodeId: Long, - icdCounter: Long, - icdDeviceInfo: ICDDeviceInfo - ) = listener.onICDRegistrationComplete(errorCode, icdNodeId, icdCounter, icdDeviceInfo) + override fun onICDRegistrationComplete(errorCode: Int, icdDeviceInfo: ICDDeviceInfo) = + listener.onICDRegistrationComplete(errorCode, icdDeviceInfo) override fun onError(error: Throwable) = listener.onError(error) diff --git a/src/controller/java/src/matter/controller/MatterController.kt b/src/controller/java/src/matter/controller/MatterController.kt index 77b0664f76d7ec..535d78eae5dc96 100644 --- a/src/controller/java/src/matter/controller/MatterController.kt +++ b/src/controller/java/src/matter/controller/MatterController.kt @@ -66,12 +66,7 @@ interface MatterController : Closeable, InteractionClient { fun onICDRegistrationInfoRequired() /** Notifies when the registration flow for the ICD completes. */ - fun onICDRegistrationComplete( - errorCode: Int, - icdNodeId: Long, - icdCounter: Long, - icdDeviceInfo: ICDDeviceInfo - ) + fun onICDRegistrationComplete(errorCode: Int, icdDeviceInfo: ICDDeviceInfo) } /**