Skip to content

Commit

Permalink
[Android] Use GetDeviceBeingCommissioned for network commissioning (#…
Browse files Browse the repository at this point in the history
…11658)

* Use GetDeviceBeingCommissioned for network commissioning

* Restyled by clang-format

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Jul 6, 2023
1 parent d0bb669 commit 1489600
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))
Expand All @@ -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 {
Expand All @@ -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

Expand All @@ -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) {
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -290,13 +277,20 @@ 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()
}

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
Expand Down
26 changes: 26 additions & 0 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,39 @@ 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>(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<jlong>(commissioneeDevice);
}

JNI_METHOD(void, getConnectedDevicePointer)(JNIEnv * env, jobject self, jlong handle, jlong nodeId, jlong callbackHandle)
{
chip::DeviceLayer::StackLock lock;
AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle);

GetConnectedDeviceCallback * connectedDeviceCallback = reinterpret_cast<GetConnectedDeviceCallback *>(callbackHandle);
VerifyOrReturn(connectedDeviceCallback != nullptr, ChipLogError(Controller, "GetConnectedDeviceCallback handle is nullptr"));
wrapper->Controller()->GetCompressedFabricId();
wrapper->Controller()->GetConnectedDevice(nodeId, &connectedDeviceCallback->mOnSuccess, &connectedDeviceCallback->mOnFailure);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ public void pairDevice(BluetoothGatt bleServer, int connId, long deviceId, long
/**
* Pair a device connected through BLE.
*
* <p>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
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 1489600

Please sign in to comment.