From 8917652af0b8a694bd50a48607b07fa9434c8f06 Mon Sep 17 00:00:00 2001 From: Austin Hsieh <77706079+austinh0@users.noreply.github.com> Date: Thu, 11 Nov 2021 11:06:36 -0800 Subject: [PATCH] [Android] Use GetDeviceBeingCommissioned for network commissioning (#11658) * Use GetDeviceBeingCommissioned for network commissioning * Restyled by clang-format Co-authored-by: Restyled.io --- .../provisioning/EnterNetworkFragment.kt | 38 ++++++++----------- .../java/CHIPDeviceController-JNI.cpp | 26 +++++++++++++ .../ChipDeviceController.java | 12 +++++- 3 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt b/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt index afee7fe7c2c6fe..7d63116c3d1213 100644 --- a/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt +++ b/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/EnterNetworkFragment.kt @@ -24,7 +24,6 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment -import androidx.lifecycle.lifecycleScope import chip.devicecontroller.ChipClusters.NetworkCommissioningCluster import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.R @@ -37,16 +36,11 @@ import kotlinx.android.synthetic.main.enter_thread_network_fragment.xpanIdEd import kotlinx.android.synthetic.main.enter_wifi_network_fragment.pwdEd import kotlinx.android.synthetic.main.enter_wifi_network_fragment.ssidEd import kotlinx.android.synthetic.main.enter_wifi_network_fragment.view.saveNetworkBtn -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch /** * Fragment to collect Wi-Fi network information from user and send it to device being provisioned. */ class EnterNetworkFragment : Fragment() { - - private lateinit var scope: CoroutineScope - private val networkType: ProvisionNetworkType get() = requireNotNull( ProvisionNetworkType.fromName(arguments?.getString(ARG_PROVISION_NETWORK_TYPE)) @@ -57,15 +51,13 @@ class EnterNetworkFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - scope = viewLifecycleOwner.lifecycleScope - val layoutRes = when (networkType) { ProvisionNetworkType.WIFI -> R.layout.enter_wifi_network_fragment ProvisionNetworkType.THREAD -> R.layout.enter_thread_network_fragment } if (USE_HARDCODED_WIFI) { - scope.launch { saveHardcodedWifiNetwork() } + saveHardcodedWifiNetwork() } return inflater.inflate(layoutRes, container, false).apply { @@ -75,17 +67,17 @@ class EnterNetworkFragment : Fragment() { private fun onSaveNetworkClicked() { if (networkType == ProvisionNetworkType.WIFI) { - scope.launch { saveWifiNetwork() } + saveWifiNetwork() } else { - scope.launch { saveThreadNetwork() } + saveThreadNetwork() } } - private suspend fun saveHardcodedWifiNetwork() { + private fun saveHardcodedWifiNetwork() { addAndEnableWifiNetwork(HARDCODED_WIFI_SSID, HARDCODED_WIFI_PASSWORD) } - private suspend fun saveWifiNetwork() { + private fun saveWifiNetwork() { val ssid = ssidEd?.text val pwd = pwdEd?.text @@ -97,15 +89,12 @@ class EnterNetworkFragment : Fragment() { addAndEnableWifiNetwork(ssid.toString(), pwd.toString()) } - private suspend fun addAndEnableWifiNetwork(ssid: String, password: String) { + private fun addAndEnableWifiNetwork(ssid: String, password: String) { // Uses UTF-8 as default val ssidBytes = ssid.toByteArray() val pwdBytes = password.toByteArray() - val devicePtr = - ChipClient.getConnectedDevicePointer(requireContext(), DeviceIdUtil.getLastDeviceId(requireContext())) - val cluster = NetworkCommissioningCluster(devicePtr, /* endpointId = */ 0) - + val cluster = createNetworkCommissioningCluster() val enableNetworkCallback = object : NetworkCommissioningCluster.EnableNetworkResponseCallback { override fun onSuccess(errorCode: Int, debugText: String) { @@ -157,7 +146,7 @@ class EnterNetworkFragment : Fragment() { }, ssidBytes, pwdBytes, /* breadcrumb = */ 0L, ADD_NETWORK_TIMEOUT) } - private suspend fun saveThreadNetwork() { + private fun saveThreadNetwork() { val channelStr = channelEd.text val panIdStr = panIdEd.text @@ -193,9 +182,7 @@ class EnterNetworkFragment : Fragment() { return } - val devicePtr = - ChipClient.getConnectedDevicePointer(requireContext(), DeviceIdUtil.getLastDeviceId(requireContext())) - val cluster = NetworkCommissioningCluster(devicePtr, /* endpointId = */ 0) + val cluster = createNetworkCommissioningCluster() val operationalDataset = makeThreadOperationalDataset( channelStr.toString().toInt(), @@ -290,6 +277,12 @@ class EnterNetworkFragment : Fragment() { return dataset } + private fun createNetworkCommissioningCluster(): NetworkCommissioningCluster { + val devicePtr = ChipClient.getDeviceController(requireContext()) + .getDeviceBeingCommissionedPointer(DeviceIdUtil.getLastDeviceId(requireContext())) + return NetworkCommissioningCluster(devicePtr, NETWORK_COMMISSIONING_CLUSTER_ENDPOINT) + } + private fun String.hexToByteArray(): ByteArray { return chunked(2).map { byteStr -> byteStr.toUByte(16).toByte() }.toByteArray() } @@ -297,6 +290,7 @@ class EnterNetworkFragment : Fragment() { companion object { private const val TAG = "EnterNetworkFragment" private const val ARG_PROVISION_NETWORK_TYPE = "provision_network_type" + private const val NETWORK_COMMISSIONING_CLUSTER_ENDPOINT = 0 // TODO(#5035): remove hardcoded option when delayed commands work. private const val USE_HARDCODED_WIFI = false diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index c708f843f619fa..339e2561ea6857 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -277,6 +277,31 @@ JNI_METHOD(void, stopDevicePairing)(JNIEnv * env, jobject self, jlong handle, jl } } +JNI_METHOD(jlong, getDeviceBeingCommissionedPointer)(JNIEnv * env, jobject self, jlong handle, jlong nodeId) +{ + chip::DeviceLayer::StackLock lock; + CHIP_ERROR err = CHIP_NO_ERROR; + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + + CommissioneeDeviceProxy * commissioneeDevice = nullptr; + err = wrapper->Controller()->GetDeviceBeingCommissioned(static_cast(nodeId), &commissioneeDevice); + + if (commissioneeDevice == nullptr) + { + ChipLogError(Controller, "Commissionee device was nullptr"); + err = CHIP_ERROR_INCORRECT_STATE; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to get commissionee device: %s", ErrorStr(err)); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + return 0; + } + + return reinterpret_cast(commissioneeDevice); +} + JNI_METHOD(void, getConnectedDevicePointer)(JNIEnv * env, jobject self, jlong handle, jlong nodeId, jlong callbackHandle) { chip::DeviceLayer::StackLock lock; @@ -284,6 +309,7 @@ JNI_METHOD(void, getConnectedDevicePointer)(JNIEnv * env, jobject self, jlong ha GetConnectedDeviceCallback * connectedDeviceCallback = reinterpret_cast(callbackHandle); VerifyOrReturn(connectedDeviceCallback != nullptr, ChipLogError(Controller, "GetConnectedDeviceCallback handle is nullptr")); + wrapper->Controller()->GetCompressedFabricId(); wrapper->Controller()->GetConnectedDevice(nodeId, &connectedDeviceCallback->mOnSuccess, &connectedDeviceCallback->mOnFailure); } diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 5ed8c507d4b094..793048dd7b0cf3 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -52,8 +52,6 @@ public void pairDevice(BluetoothGatt bleServer, int connId, long deviceId, long /** * Pair a device connected through BLE. * - *

TODO(#7985): Annotate csrNonce as Nullable. - * * @param bleServer the BluetoothGatt representing the BLE connection to the device * @param connId the BluetoothGatt Id representing the BLE connection to the device * @param deviceId the node ID to assign to the device @@ -100,6 +98,14 @@ public void unpairDevice(long deviceId) { unpairDevice(deviceControllerPtr, deviceId); } + /** + * Returns a pointer to a device currently being commissioned. This should be used before the + * device is operationally available. + */ + public long getDeviceBeingCommissionedPointer(long nodeId) { + return getDeviceBeingCommissionedPointer(deviceControllerPtr, nodeId); + } + /** * Through GetConnectedDeviceCallback, returns a pointer to a connected device or an error. * @@ -251,6 +257,8 @@ private native void pairDeviceWithAddress( private native void unpairDevice(long deviceControllerPtr, long deviceId); + private native long getDeviceBeingCommissionedPointer(long deviceControllerPtr, long nodeId); + private native void getConnectedDevicePointer( long deviceControllerPtr, long deviceId, long callbackHandle);