diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 6478bc2a0bece8..abc783119beced 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -330,12 +330,12 @@ CHIP_ERROR AndroidDeviceControllerWrapper::ApplyNetworkCredentials(chip::Control else if (threadCredentialsJava != nullptr) { jmethodID getOperationalDataset; - err = chip::JniReferences::GetInstance().FindMethod(env, wifiCredentialsJava, "getOperationalDataset", "()[B", + err = chip::JniReferences::GetInstance().FindMethod(env, threadCredentialsJava, "getOperationalDataset", "()[B", &getOperationalDataset); VerifyOrReturnError(err == CHIP_NO_ERROR, err); operationalDatasetBytes = static_cast(env->NewGlobalRef(env->CallObjectMethod(threadCredentialsJava, getOperationalDataset))); - VerifyOrReturnError(ssidStr != nullptr && !env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN); + VerifyOrReturnError(operationalDatasetBytes != nullptr && !env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN); operationalDataset = env->GetByteArrayElements(operationalDatasetBytes, nullptr); jsize length = env->GetArrayLength(operationalDatasetBytes); diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index cbb592bdde4d6e..f80a21896e327d 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -177,6 +177,33 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self) return result; } +JNI_METHOD(void, commissionDevice) +(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jbyteArray csrNonce, jobject networkCredentials) +{ + chip::DeviceLayer::StackLock lock; + CHIP_ERROR err = CHIP_NO_ERROR; + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + + ChipLogProgress(Controller, "commissionDevice() called"); + + CommissioningParameters commissioningParams = CommissioningParameters(); + err = wrapper->ApplyNetworkCredentials(commissioningParams, networkCredentials); + VerifyOrExit(err == CHIP_NO_ERROR, err = CHIP_ERROR_INVALID_ARGUMENT); + + if (csrNonce != nullptr) + { + JniByteArray jniCsrNonce(env, csrNonce); + commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan()); + } + err = wrapper->Controller()->Commission(deviceId, commissioningParams); +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to commission the device."); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + } +} + JNI_METHOD(void, pairDevice) (JNIEnv * env, jobject self, jlong handle, jlong deviceId, jint connObj, jlong pinCode, jbyteArray csrNonce, jobject networkCredentials) @@ -268,6 +295,31 @@ JNI_METHOD(void, establishPaseConnection)(JNIEnv * env, jobject self, jlong hand } } +JNI_METHOD(void, establishPaseConnectionByAddress) +(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jstring address, jint port, jlong pinCode) +{ + chip::DeviceLayer::StackLock lock; + CHIP_ERROR err = CHIP_NO_ERROR; + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + + Inet::IPAddress addr; + JniUtfString addrJniString(env, address); + VerifyOrReturn(Inet::IPAddress::FromString(addrJniString.c_str(), addr), + ChipLogError(Controller, "Failed to parse IP address."), + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, CHIP_ERROR_INVALID_ARGUMENT)); + + RendezvousParameters rendezvousParams = + RendezvousParameters().SetSetupPINCode(pinCode).SetPeerAddress(Transport::PeerAddress::UDP(addr, port)); + + err = wrapper->Controller()->EstablishPASEConnection(deviceId, rendezvousParams); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to establish PASE connection."); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + } +} + JNI_METHOD(void, unpairDevice)(JNIEnv * env, jobject self, jlong handle, jlong deviceId) { chip::DeviceLayer::StackLock lock; diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 82cb82fd31126f..477e47058bf5ac 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -120,6 +120,45 @@ public void establishPaseConnection(long deviceId, int connId, long setupPincode } } + /** + * Establish a secure PASE connection to the given device via IP address. + * + * @param deviceId the ID of the node to connect to + * @param address the IP address at which the node is located + * @param port the port at which the node is located + * @param setupPincode the pincode for this node + */ + public void establishPaseConnection(long deviceId, String address, int port, long setupPincode) { + Log.d(TAG, "Establishing PASE connection with ID: " + deviceId); + establishPaseConnectionByAddress(deviceControllerPtr, deviceId, address, port, setupPincode); + } + + /** + * Initiates the automatic commissioning flow using the specified network credentials. It is + * expected that a secure session has already been established via {@link + * #establishPaseConnection(long, int, long)}. + * + * @param deviceId the ID of the node to be commissioned + * @param networkCredentials the credentials (Wi-Fi or Thread) to be provisioned + */ + public void commissionDevice(long deviceId, NetworkCredentials networkCredentials) { + commissionDevice(deviceControllerPtr, deviceId, /* csrNonce= */ null, networkCredentials); + } + + /** + * Initiates the automatic commissioning flow using the specified network credentials. It is + * expected that a secure session has already been established via {@link + * #establishPaseConnection(long, int, long)}. + * + * @param deviceId the ID of the node to be commissioned + * @param csrNonce a nonce to be used for the CSR request + * @param networkCredentials the credentials (Wi-Fi or Thread) to be provisioned + */ + public void commissionDevice( + long deviceId, @Nullable byte[] csrNonce, NetworkCredentials networkCredentials) { + commissionDevice(deviceControllerPtr, deviceId, csrNonce, networkCredentials); + } + public void unpairDevice(long deviceId) { unpairDevice(deviceControllerPtr, deviceId); } @@ -285,6 +324,15 @@ private native void pairDeviceWithAddress( private native void establishPaseConnection( long deviceControllerPtr, long deviceId, int connId, long setupPincode); + private native void establishPaseConnectionByAddress( + long deviceControllerPtr, long deviceId, String address, int port, long setupPincode); + + private native void commissionDevice( + long deviceControllerPtr, + long deviceId, + @Nullable byte[] csrNonce, + NetworkCredentials networkCredentials); + private native void unpairDevice(long deviceControllerPtr, long deviceId); private native long getDeviceBeingCommissionedPointer(long deviceControllerPtr, long nodeId);