Skip to content

Commit

Permalink
Add additional commissioning bindings to support BLE/IP auto-commissi…
Browse files Browse the repository at this point in the history
…oning (#13427)

1. Fixes a bug in ApplyNetworkCredentials, where the Wi-Fi objects were
   being referenced instead of the Thread objects. Additionally, added
   an exit block and ensured this method passes successfully before
   continuing on to Commission().

2. Added a binding for establishPaseSession to support IP commissioning.

3. Added a binding for Commission, which is in addition to the existing
   PairDevice binding. This is needed when PASE establishment happens
   separately from commissioning initiation.
  • Loading branch information
g-coppock authored and pull[bot] committed Mar 12, 2022
1 parent 64c2791 commit 688d5fb
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/controller/java/AndroidDeviceControllerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<jbyteArray>(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);
Expand Down
52 changes: 52 additions & 0 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 688d5fb

Please sign in to comment.