diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 3b573daa93028c..ff42d1b43a42f4 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -450,6 +450,7 @@ android_library("java") { "src/chip/devicecontroller/ChipCommandType.java", "src/chip/devicecontroller/ChipDeviceController.java", "src/chip/devicecontroller/ChipDeviceControllerException.java", + "src/chip/devicecontroller/CommissioningWindowStatus.java", "src/chip/devicecontroller/ConnectionFailureException.java", "src/chip/devicecontroller/ControllerParams.java", "src/chip/devicecontroller/DeviceAttestationDelegate.java", @@ -469,6 +470,7 @@ android_library("java") { "src/chip/devicecontroller/OTAProviderDelegate.java", "src/chip/devicecontroller/OpenCommissioningCallback.java", "src/chip/devicecontroller/OperationalKeyConfig.java", + "src/chip/devicecontroller/PairingHintBitmap.java", "src/chip/devicecontroller/PaseVerifierParams.java", "src/chip/devicecontroller/ReportCallback.java", "src/chip/devicecontroller/ReportCallbackJni.java", diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index fc2c0694b29849..99520d1a32c9a0 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -1897,9 +1897,19 @@ JNI_METHOD(jobject, getDiscoveredDevice)(JNIEnv * env, jobject self, jlong handl jclass discoveredDeviceCls = env->FindClass("chip/devicecontroller/DiscoveredDevice"); jmethodID constructor = env->GetMethodID(discoveredDeviceCls, "", "()V"); - jfieldID discrminatorID = env->GetFieldID(discoveredDeviceCls, "discriminator", "J"); - jfieldID ipAddressID = env->GetFieldID(discoveredDeviceCls, "ipAddress", "Ljava/lang/String;"); - jfieldID portID = env->GetFieldID(discoveredDeviceCls, "port", "I"); + jfieldID discrminatorID = env->GetFieldID(discoveredDeviceCls, "discriminator", "J"); + jfieldID ipAddressID = env->GetFieldID(discoveredDeviceCls, "ipAddress", "Ljava/lang/String;"); + jfieldID portID = env->GetFieldID(discoveredDeviceCls, "port", "I"); + jfieldID deviceTypeID = env->GetFieldID(discoveredDeviceCls, "deviceType", "J"); + jfieldID vendorIdID = env->GetFieldID(discoveredDeviceCls, "vendorId", "I"); + jfieldID productIdID = env->GetFieldID(discoveredDeviceCls, "productId", "I"); + jfieldID rotatingIdID = env->GetFieldID(discoveredDeviceCls, "rotatingId", "[B"); + jfieldID instanceNameID = env->GetFieldID(discoveredDeviceCls, "instanceName", "Ljava/lang/String;"); + jfieldID deviceNameID = env->GetFieldID(discoveredDeviceCls, "deviceName", "Ljava/lang/String;"); + jfieldID pairingInstructionID = env->GetFieldID(discoveredDeviceCls, "pairingInstruction", "Ljava/lang/String;"); + + jmethodID setCommissioningModeID = env->GetMethodID(discoveredDeviceCls, "setCommissioningMode", "(I)V"); + jmethodID setPairingHintID = env->GetMethodID(discoveredDeviceCls, "setPairingHint", "(I)V"); jobject discoveredObj = env->NewObject(discoveredDeviceCls, constructor); @@ -1911,6 +1921,26 @@ JNI_METHOD(jobject, getDiscoveredDevice)(JNIEnv * env, jobject self, jlong handl env->SetObjectField(discoveredObj, ipAddressID, jniipAdress); env->SetIntField(discoveredObj, portID, static_cast(data->resolutionData.port)); + env->SetLongField(discoveredObj, deviceTypeID, static_cast(data->commissionData.deviceType)); + env->SetIntField(discoveredObj, vendorIdID, static_cast(data->commissionData.vendorId)); + env->SetIntField(discoveredObj, productIdID, static_cast(data->commissionData.productId)); + + jbyteArray jRotatingId; + CHIP_ERROR err = JniReferences::GetInstance().N2J_ByteArray( + env, data->commissionData.rotatingId, static_cast(data->commissionData.rotatingIdLen), jRotatingId); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "jRotatingId N2J_ByteArray error : %" CHIP_ERROR_FORMAT, err.Format()); + return nullptr; + } + env->SetObjectField(discoveredObj, rotatingIdID, static_cast(jRotatingId)); + env->SetObjectField(discoveredObj, instanceNameID, env->NewStringUTF(data->commissionData.instanceName)); + env->SetObjectField(discoveredObj, deviceNameID, env->NewStringUTF(data->commissionData.deviceName)); + env->SetObjectField(discoveredObj, pairingInstructionID, env->NewStringUTF(data->commissionData.pairingInstruction)); + + env->CallVoidMethod(discoveredObj, setCommissioningModeID, static_cast(data->commissionData.commissioningMode)); + env->CallVoidMethod(discoveredObj, setPairingHintID, static_cast(data->commissionData.pairingHint)); return discoveredObj; } diff --git a/src/controller/java/src/chip/devicecontroller/CommissioningWindowStatus.java b/src/controller/java/src/chip/devicecontroller/CommissioningWindowStatus.java new file mode 100644 index 00000000000000..bfced35f778b78 --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/CommissioningWindowStatus.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller; + +public enum CommissioningWindowStatus { + WindowNotOpen(0), + EnhancedWindowOpen(1), + BasicWindowOpen(2); + + private final int value; + + CommissioningWindowStatus(int value) { + this.value = value; + } + + public static CommissioningWindowStatus value(int value) { + for (CommissioningWindowStatus status : CommissioningWindowStatus.values()) { + if (status.value == value) { + return status; + } + } + throw new IllegalArgumentException("Invalid value: " + value); + } +} diff --git a/src/controller/java/src/chip/devicecontroller/DiscoveredDevice.java b/src/controller/java/src/chip/devicecontroller/DiscoveredDevice.java index 01d6ecc28cce42..2fb8bcf4e79842 100644 --- a/src/controller/java/src/chip/devicecontroller/DiscoveredDevice.java +++ b/src/controller/java/src/chip/devicecontroller/DiscoveredDevice.java @@ -17,8 +17,66 @@ */ package chip.devicecontroller; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + public class DiscoveredDevice { public long discriminator; public String ipAddress; public int port; + public long deviceType; + public int vendorId; + public int productId; + public Set pairingHint; + public CommissioningWindowStatus commissioningMode; + public byte[] rotatingId; + public String instanceName; + public String deviceName; + public String pairingInstruction; + + // For use in JNI. + private void setCommissioningMode(int value) { + this.commissioningMode = CommissioningWindowStatus.value(value); + } + + private void setPairingHint(int value) { + this.pairingHint = new HashSet<>(); + for (PairingHintBitmap mode : PairingHintBitmap.values()) { + int bitmask = 1 << mode.getBitIndex(); + if ((value & bitmask) != 0) { + pairingHint.add(mode); + } + } + } + + @Override + public String toString() { + return "DiscoveredDevice : {" + + "\n\tdiscriminator : " + + discriminator + + "\n\tipAddress : " + + ipAddress + + "\n\tport : " + + port + + "\n\tdeviceType : " + + deviceType + + "\n\tvendorId : " + + vendorId + + "\n\tproductId : " + + productId + + "\n\tpairingHint : " + + pairingHint + + "\n\tcommissioningMode : " + + commissioningMode + + "\n\trotatingId : " + + (rotatingId != null ? Arrays.toString(rotatingId) : "null") + + "\n\tinstanceName : " + + instanceName + + "\n\tdeviceName : " + + deviceName + + "\n\tpairingInstruction : " + + pairingInstruction + + "\n}"; + } } diff --git a/src/controller/java/src/chip/devicecontroller/PairingHintBitmap.java b/src/controller/java/src/chip/devicecontroller/PairingHintBitmap.java new file mode 100644 index 00000000000000..d13b710c9c1b98 --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/PairingHintBitmap.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller; + +public enum PairingHintBitmap { + PowerCycle(0, false), + DeviceManufacturerURL(1, false), + Administrator(2, false), + SettingsMenuOnTheNode(3, false), + CustomInstruction(4, true), + DeviceManual(5, false), + PressResetButton(6, false), + PressResetButtonWithApplicationOfPower(7, false), + PressResetButtonForNseconds(8, true), + PressResetButtonUntilLightBlinks(9, true), + PressResetButtonForNsecondsWithApplicationOfPower(10, true), + PressResetButtonUntilLightBlinksWithApplicationOfPower(11, true), + PressResetButtonNTimes(12, true), + PressSetupButton(13, false), + PressSetupButtonWithApplicationOfPower(14, false), + PressSetupButtonForNseconds(15, true), + PressSetupButtonUntilLightBlinks(16, true), + PressSetupButtonForNsecondsWithApplicationOfPower(17, true), + PressSetupButtonUntilLightBlinksWithApplicationOfPower(18, true), + PressSetupButtonNtimes(19, true); + + private final int bitIndex; + private final boolean isRequirePairingInstruction; + + PairingHintBitmap(int bitIndex, boolean isRequirePairingInstruction) { + this.bitIndex = bitIndex; + this.isRequirePairingInstruction = isRequirePairingInstruction; + } + + public int getBitIndex() { + return bitIndex; + } + + public boolean getRequirePairingInstruction() { + return isRequirePairingInstruction; + } +}