diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 3b4c4b204782a9..75a682a41331b5 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -257,7 +257,8 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self) return result; } -JNI_METHOD(void, pairDevice)(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jint connObj, jlong pinCode) +JNI_METHOD(void, pairDevice) +(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jint connObj, jlong pinCode, jbyteArray csrNonce) { StackLockGuard lock(JniReferences::GetInstance().GetStackLock()); CHIP_ERROR err = CHIP_NO_ERROR; @@ -271,6 +272,11 @@ JNI_METHOD(void, pairDevice)(JNIEnv * env, jobject self, jlong handle, jlong dev .SetConnectionObject(reinterpret_cast(connObj)) .SetBleLayer(&sBleLayer) .SetPeerAddress(Transport::PeerAddress::BLE()); + if (csrNonce != nullptr) + { + JniByteArray jniCsrNonce(env, csrNonce); + params = params.SetCSRNonce(jniCsrNonce.byteSpan()); + } err = wrapper->Controller()->PairDevice(deviceId, params); if (err != CHIP_NO_ERROR) diff --git a/src/controller/java/JniTypeWrappers.h b/src/controller/java/JniTypeWrappers.h index 333b89841d4179..1f5f7cdb2338fe 100644 --- a/src/controller/java/JniTypeWrappers.h +++ b/src/controller/java/JniTypeWrappers.h @@ -18,6 +18,7 @@ #pragma once #include +#include /// Exposes the underlying UTF string from a jni string class JniUtfString @@ -44,6 +45,7 @@ class JniByteArray ~JniByteArray() { mEnv->ReleaseByteArrayElements(mArray, mData, 0); } const jbyte * data() const { return mData; } + chip::ByteSpan byteSpan() const { return chip::ByteSpan(reinterpret_cast(data()), size()); } jsize size() const { return mDataLength; } private: diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index defe6d3f743755..6f196f0b1f2496 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -47,6 +47,22 @@ public BluetoothGattCallback getCallback() { } public void pairDevice(BluetoothGatt bleServer, long deviceId, long setupPincode) { + pairDevice(bleServer, deviceId, setupPincode, null); + } + + /** + * Pair a device connected through BLE. + * + *

TODO(#7985): Annotate csrNonce as Nullable. + * + * @param bleServer the BluetoothGatt representing the BLE connection to the device + * @param deviceId the node ID to assign to the device + * @param setupPincode the pincode for the device + * @param csrNonce the 32-byte CSR nonce to use, or null if we want to use an internally randomly + * generated CSR nonce. + */ + public void pairDevice( + BluetoothGatt bleServer, long deviceId, long setupPincode, byte[] csrNonce) { if (connectionId == 0) { bleGatt = bleServer; @@ -59,7 +75,7 @@ public void pairDevice(BluetoothGatt bleServer, long deviceId, long setupPincode Log.d(TAG, "Bluetooth connection added with ID: " + connectionId); Log.d(TAG, "Pairing device with ID: " + deviceId); - pairDevice(deviceControllerPtr, deviceId, connectionId, setupPincode); + pairDevice(deviceControllerPtr, deviceId, connectionId, setupPincode, csrNonce); } else { Log.e(TAG, "Bluetooth connection already in use."); completionListener.onError(new Exception("Bluetooth connection already in use.")); @@ -74,10 +90,6 @@ public void pairTestDeviceWithoutSecurity(String ipAddress) { pairTestDeviceWithoutSecurity(deviceControllerPtr, ipAddress); } - public void pairDevice(long deviceId, int connectionId, long pinCode) { - pairDevice(deviceControllerPtr, deviceId, connectionId, pinCode); - } - public long getDevicePointer(long deviceId) { return getDevicePointer(deviceControllerPtr, deviceId); } @@ -199,7 +211,7 @@ public boolean isActive(long deviceId) { private native long newDeviceController(); private native void pairDevice( - long deviceControllerPtr, long deviceId, int connectionId, long pinCode); + long deviceControllerPtr, long deviceId, int connectionId, long pinCode, byte[] csrNonce); private native void unpairDevice(long deviceControllerPtr, long deviceId); diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m index 8816c86b42717c..6574e7bb7a1d46 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m @@ -714,7 +714,7 @@ - (void)handleRendezVousBLE:(uint16_t)discriminator setupPINCode:(uint32_t)setup { NSError * error; uint64_t deviceID = CHIPGetNextAvailableDeviceID(); - if ([self.chipController pairDevice:deviceID discriminator:discriminator setupPINCode:setupPINCode error:&error]) { + if ([self.chipController pairDevice:deviceID discriminator:discriminator setupPINCode:setupPINCode csrNonce:nil error:&error]) { deviceID++; CHIPSetNextAvailableDeviceID(deviceID); } diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.h b/src/darwin/Framework/CHIP/CHIPDeviceController.h index cc5945e3f464fe..6b03a831403345 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.h +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.h @@ -36,6 +36,7 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)pairDevice:(uint64_t)deviceID discriminator:(uint16_t)discriminator setupPINCode:(uint32_t)setupPINCode + csrNonce:(nullable NSData *)csrNonce error:(NSError * __autoreleasing *)error; - (BOOL)pairDevice:(uint64_t)deviceID diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.mm b/src/darwin/Framework/CHIP/CHIPDeviceController.mm index 0e0d3016921916..cf3e52e28988bb 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.mm +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.mm @@ -212,6 +212,7 @@ - (NSNumber *)_getControllerNodeId - (BOOL)pairDevice:(uint64_t)deviceID discriminator:(uint16_t)discriminator setupPINCode:(uint32_t)setupPINCode + csrNonce:(nullable NSData *)csrNonce error:(NSError * __autoreleasing *)error { __block CHIP_ERROR errorCode = CHIP_ERROR_INCORRECT_STATE; @@ -224,6 +225,10 @@ - (BOOL)pairDevice:(uint64_t)deviceID chip::RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode).SetDiscriminator(discriminator); + if (csrNonce != nil) { + params = params.SetCSRNonce(chip::ByteSpan((const uint8_t *) csrNonce.bytes, csrNonce.length)); + } + if ([self isRunning]) { _operationalCredentialsDelegate->SetDeviceID(deviceID); errorCode = self.cppCommissioner->PairDevice(deviceID, params); @@ -306,7 +311,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID uint16_t discriminator = setupPayload.discriminator.unsignedShortValue; uint32_t setupPINCode = setupPayload.setUpPINCode.unsignedIntValue; _operationalCredentialsDelegate->SetDeviceID(deviceID); - didSucceed = [self pairDevice:deviceID discriminator:discriminator setupPINCode:setupPINCode error:error]; + didSucceed = [self pairDevice:deviceID discriminator:discriminator setupPINCode:setupPINCode csrNonce:nil error:error]; } else { CHIP_LOG_ERROR("Failed to create CHIPSetupPayload for pairing with error %@", *error); }