Skip to content

Commit

Permalink
Replace hand-written Thread provisioning code with Java clusters (#9282)
Browse files Browse the repository at this point in the history
  • Loading branch information
austinh0 authored and pull[bot] committed Sep 2, 2021
1 parent 1e1b73c commit 0ffa033
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ open class GenericChipDeviceListener : ChipDeviceController.CompletionListener {
// No op
}

override fun onNetworkCommissioningComplete(code: Int) {
// No op
}

override fun onNotifyChipConnectionClosed() {
// No op
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,19 +175,6 @@ class DeviceProvisioningFragment : Fragment() {
Log.d(TAG, "onPairingDeleted: $code")
}

override fun onNetworkCommissioningComplete(code: Int) {
Log.d(TAG, "onNetworkCommissioningComplete: $code")

if (code == 0) {
showMessage(R.string.rendezvous_over_ble_commissioning_success_text)
} else {
showMessage(R.string.rendezvous_over_ble_commissioning_failure_text)
}

FragmentUtil.getHost(this@DeviceProvisioningFragment, Callback::class.java)
?.onCommissioningComplete(code)
}

override fun onCloseBleComplete() {
Log.d(TAG, "onCloseBleComplete")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import chip.devicecontroller.ChipClusters.NetworkCommissioningCluster
import chip.devicecontroller.ChipDeviceControllerException
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.util.DeviceIdUtil
Expand Down Expand Up @@ -148,7 +147,7 @@ class EnterNetworkFragment : Fragment() {
DeviceProvisioningFragment.Callback::class.java
)?.onCommissioningComplete(-1)
}
}, ssidBytes, pwdBytes, /* breadcrumb = */ 0L, ADD_WIFI_NETWORK_TIMEOUT)
}, ssidBytes, pwdBytes, /* breadcrumb = */ 0L, ADD_NETWORK_TIMEOUT)
}

private fun saveThreadNetwork() {
Expand Down Expand Up @@ -187,28 +186,73 @@ class EnterNetworkFragment : Fragment() {
return
}

try {
ChipClient.getDeviceController(requireContext()).enableThreadNetwork(
DeviceIdUtil.getLastDeviceId(requireContext()),
MakeThreadOperationalDataset(
channelStr.toString().toInt(),
panIdStr.toString().toInt(16),
val devicePtr = ChipClient.getDeviceController(requireContext())
.getDevicePointer(DeviceIdUtil.getLastDeviceId(requireContext()))
val cluster = NetworkCommissioningCluster(devicePtr, /* endpointId = */ 0)

val operationalDataset = makeThreadOperationalDataset(
channelStr.toString().toInt(),
panIdStr.toString().toInt(16),
xpanIdStr.hexToByteArray(),
masterKeyStr.hexToByteArray()
)

val enableNetworkCallback = object :
NetworkCommissioningCluster.EnableNetworkResponseCallback {
override fun onSuccess(errorCode: Int, debugText: String) {
Log.v(TAG, "EnableNetwork for $panIdStr succeeded, proceeding to OnOff")

requireActivity().runOnUiThread {
Toast.makeText(
requireContext(),
R.string.rendezvous_over_ble_commissioning_success_text,
Toast.LENGTH_SHORT
).show()
}

FragmentUtil.getHost(
this@EnterNetworkFragment,
DeviceProvisioningFragment.Callback::class.java
)?.onCommissioningComplete(0)
}

override fun onError(ex: Exception) {
Log.e(TAG, "EnableNetwork for $panIdStr failed", ex)
// TODO: consolidate error codes
FragmentUtil.getHost(
this@EnterNetworkFragment,
DeviceProvisioningFragment.Callback::class.java
)?.onCommissioningComplete(-1)
}
}

cluster.addThreadNetwork(object :
NetworkCommissioningCluster.AddThreadNetworkResponseCallback {
override fun onSuccess(errorCode: Int, debugText: String) {
Log.v(TAG, "AddThreadNetwork for $panIdStr succeeded")
println(xpanIdStr.toByteArray())
for( b in xpanIdStr.toByteArray()) {
println("> $b")
}
cluster.enableNetwork(
enableNetworkCallback,
xpanIdStr.hexToByteArray(),
masterKeyStr.hexToByteArray()
/* breadcrumb = */ 0L,
ENABLE_NETWORK_TIMEOUT
)
)
} catch (e: ChipDeviceControllerException) {
Toast.makeText(
requireContext(),
R.string.rendezvous_over_ble_commissioning_failure_text,
Toast.LENGTH_SHORT
).show()
FragmentUtil.getHost(this, DeviceProvisioningFragment.Callback::class.java)
?.onCommissioningComplete(e.errorCode)
}
}

override fun onError(ex: Exception) {
Log.e(TAG, "AddThreadNetwork for $panIdStr failed", ex)
FragmentUtil.getHost(
this@EnterNetworkFragment,
DeviceProvisioningFragment.Callback::class.java
)?.onCommissioningComplete(-1)
}
}, operationalDataset, /* breadcrumb = */ 0L, ADD_NETWORK_TIMEOUT)
}

private fun MakeThreadOperationalDataset(
private fun makeThreadOperationalDataset(
channel: Int,
panId: Int,
xpanId: ByteArray,
Expand Down Expand Up @@ -251,7 +295,7 @@ class EnterNetworkFragment : Fragment() {
private const val USE_HARDCODED_WIFI = false
private const val HARDCODED_WIFI_SSID = ""
private const val HARDCODED_WIFI_PASSWORD = ""
private const val ADD_WIFI_NETWORK_TIMEOUT = 10000L
private const val ADD_NETWORK_TIMEOUT = 10000L
private const val ENABLE_NETWORK_TIMEOUT = 10000L

private const val NUM_CHANNEL_BYTES = 3
Expand Down
114 changes: 0 additions & 114 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@
#include <support/ThreadOperationalDataset.h>
#include <support/logging/CHIPLogging.h>

#include <zap-generated/CHIPClientCallbacks.h>
#include <zap-generated/CHIPClusters.h>

// Choose an approximation of PTHREAD_NULL if pthread.h doesn't define one.
#ifndef PTHREAD_NULL
#define PTHREAD_NULL 0
Expand All @@ -60,7 +57,6 @@
using namespace chip;
using namespace chip::Inet;
using namespace chip::Controller;
using namespace chip::Thread;

#define JNI_METHOD(RETURN, METHOD_NAME) \
extern "C" JNIEXPORT RETURN JNICALL Java_chip_devicecontroller_ChipDeviceController_##METHOD_NAME
Expand All @@ -86,10 +82,6 @@ static CHIP_ERROR N2J_Error(JNIEnv * env, CHIP_ERROR inErr, jthrowable & outEx);

namespace {

constexpr EndpointId kNodeEndpoint = 0;
constexpr uint64_t kBreadcrumb = 0;
constexpr uint32_t kZclTimeoutMs = 10000;

JavaVM * sJVM;
System::Layer sSystemLayer;
Inet::InetLayer sInetLayer;
Expand Down Expand Up @@ -548,112 +540,6 @@ JNI_METHOD(void, sendCommand)(JNIEnv * env, jobject self, jlong handle, jlong de
}
}

namespace {

void OnAddNetworkResponse(void * context, uint8_t errorCode, uint8_t * debugText);
void OnEnableNetworkResponse(void * context, uint8_t errorCode, uint8_t * debugText);
void OnNetworkCommissioningFailed(void * context, uint8_t errorCode);

// Context used for processing "AddThreadNetwork" and "EnableNetwork" commands.
struct NetworkCommissioningCtx
{
static constexpr size_t kMaxNetworkIDLen = 32;

NetworkCommissioningCtx(JNIEnv * env, jlong handle, uint64_t deviceID, ByteSpan networkID) :
mEnv(env), mHandle(handle), mDeviceID(deviceID)
{
VerifyOrReturn(networkID.size() <= sizeof(mNetworkID), ThrowError(env, CHIP_ERROR_BUFFER_TOO_SMALL));
memcpy(mNetworkID, networkID.data(), networkID.size());
mNetworkIDLen = networkID.size();
}

JNIEnv * mEnv;
jlong mHandle;
uint64_t mDeviceID;
uint8_t mNetworkID[kMaxNetworkIDLen];
size_t mNetworkIDLen;
Callback::Callback<NetworkCommissioningClusterAddThreadNetworkResponseCallback> mOnAddNetwork{ OnAddNetworkResponse, this };
Callback::Callback<NetworkCommissioningClusterEnableNetworkResponseCallback> mOnEnableNetwork{ OnEnableNetworkResponse, this };
Callback::Callback<DefaultFailureCallback> mOnCommissioningFailed{ OnNetworkCommissioningFailed, this };
};

void FinishCommissioning(NetworkCommissioningCtx * ctx, CHIP_ERROR err)
{
AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(ctx->mHandle);
wrapper->CallJavaMethod("onNetworkCommissioningComplete", static_cast<jint>(err.AsInteger()));
delete ctx;
}

void OnAddNetworkResponse(void * context, uint8_t errorCode, uint8_t * debugText)
{
NetworkCommissioningCtx * ctx = static_cast<NetworkCommissioningCtx *>(context);
AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(ctx->mHandle);
CHIP_ERROR err = CHIP_NO_ERROR;
Device * chipDevice = nullptr;
NetworkCommissioningCluster cluster;

SuccessOrExit(err = wrapper->Controller()->GetDevice(ctx->mDeviceID, &chipDevice));

cluster.Associate(chipDevice, kNodeEndpoint);
err = cluster.EnableNetwork(ctx->mOnEnableNetwork.Cancel(), ctx->mOnCommissioningFailed.Cancel(),
ByteSpan(ctx->mNetworkID, ctx->mNetworkIDLen), kBreadcrumb, kZclTimeoutMs);

exit:
if (err != CHIP_NO_ERROR)
{
FinishCommissioning(ctx, err);
}
}

void OnEnableNetworkResponse(void * context, uint8_t errorCode, uint8_t * debugText)
{
NetworkCommissioningCtx * ctx = static_cast<NetworkCommissioningCtx *>(context);
FinishCommissioning(ctx, CHIP_NO_ERROR);
}

void OnNetworkCommissioningFailed(void * context, uint8_t errorCode)
{
NetworkCommissioningCtx * ctx = static_cast<NetworkCommissioningCtx *>(context);
FinishCommissioning(ctx, CHIP_ERROR_INTERNAL);
}

} // namespace

JNI_METHOD(void, enableThreadNetwork)
(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jbyteArray operationalDataset)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Device * chipDevice = nullptr;
OperationalDataset dataset = {};
JniByteArray datasetAccessor(env, operationalDataset);
size_t datasetLength = datasetAccessor.size();
uint8_t datasetBytes[kSizeOperationalDataset];
uint8_t extPanId[kSizeExtendedPanId];

VerifyOrExit(datasetLength <= sizeof(datasetBytes), err = CHIP_ERROR_INVALID_ARGUMENT);
memcpy(datasetBytes, datasetAccessor.data(), datasetLength);
SuccessOrExit(err = dataset.Init(ByteSpan(datasetBytes, datasetLength)));
SuccessOrExit(err = dataset.GetExtendedPanId(extPanId));
GetCHIPDevice(env, handle, deviceId, &chipDevice);

{
auto ctx = std::make_unique<NetworkCommissioningCtx>(env, handle, deviceId, ByteSpan(extPanId, sizeof(extPanId)));
StackLockGuard lock(JniReferences::GetInstance().GetStackLock());
NetworkCommissioningCluster cluster;
cluster.Associate(chipDevice, kNodeEndpoint);
SuccessOrExit(err = cluster.AddThreadNetwork(ctx->mOnAddNetwork.Cancel(), ctx->mOnCommissioningFailed.Cancel(),
dataset.AsByteSpan(), kBreadcrumb, kZclTimeoutMs));
ctx.release();
}

exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "Failed to enable Thread network");
ThrowError(env, err);
}
}

JNI_METHOD(jboolean, openPairingWindow)(JNIEnv * env, jobject self, jlong handle, jlong deviceId, jint duration)
{
StackLockGuard lock(JniReferences::GetInstance().GetStackLock());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,6 @@ public void onPairingDeleted(int errorCode) {
}
}

public void onNetworkCommissioningComplete(int errorCode) {
if (completionListener != null) {
completionListener.onNetworkCommissioningComplete(errorCode);
}
}

public void onNotifyChipConnectionClosed(int connId) {
// Clear connection state.
AndroidChipStack.getInstance().removeConnection(connId);
Expand Down Expand Up @@ -225,10 +219,6 @@ public void sendCommand(long deviceId, ChipCommandType command, int value) {
sendCommand(deviceControllerPtr, deviceId, command, value);
}

public void enableThreadNetwork(long deviceId, byte[] operationalDataset) {
enableThreadNetwork(deviceControllerPtr, deviceId, operationalDataset);
}

public boolean openPairingWindow(long deviceId, int duration) {
return openPairingWindow(deviceControllerPtr, deviceId, duration);
}
Expand Down Expand Up @@ -274,9 +264,6 @@ private native void getConnectedDevicePointer(
private native void sendCommand(
long deviceControllerPtr, long deviceId, ChipCommandType command, int value);

private native void enableThreadNetwork(
long deviceControllerPtr, long deviceId, byte[] operationalDataset);

private native boolean openPairingWindow(long deviceControllerPtr, long deviceId, int duration);

private native boolean isActive(long deviceControllerPtr, long deviceId);
Expand Down Expand Up @@ -316,9 +303,6 @@ public interface CompletionListener {
/** Notifies the completion of commissioning. */
void onCommissioningComplete(long nodeId, int errorCode);

/** Notifies the completion of network commissioning */
void onNetworkCommissioningComplete(int errorCode);

/** Notifies that the Chip connection has been closed. */
void onNotifyChipConnectionClosed();

Expand Down

0 comments on commit 0ffa033

Please sign in to comment.