Skip to content

Commit

Permalink
Added RegulatoryConfig support to AutoCommissioner for Android (#24413)
Browse files Browse the repository at this point in the history
  • Loading branch information
swan-amazon authored and pull[bot] committed Mar 4, 2023
1 parent b7db677 commit ae8377c
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 1 deletion.
1 change: 1 addition & 0 deletions examples/java-matter-controller/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ chip_system_project_config_include = "<SystemProjectConfig.h>"
chip_project_config_include_dirs =
[ "${chip_root}/examples/java-matter-controller/include" ]
chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ]
chip_stack_lock_tracking = "none"
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Project CHIP Authors
* Copyright (c) 2022-2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -105,6 +105,7 @@ public static void main(String[] args) {
ControllerParams.newBuilder()
.setUdpListenPort(0)
.setControllerVendorId(0xFFF1)
.setCountryCode("US")
.build());

CredentialsIssuer credentialsIssuer = new CredentialsIssuer();
Expand Down
60 changes: 60 additions & 0 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,16 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr
&getSkipCommissioningComplete);
SuccessOrExit(err);

jmethodID getCountryCode;
err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getCountryCode", "()Ljava/util/Optional;",
&getCountryCode);
SuccessOrExit(err);

jmethodID getRegulatoryLocation;
err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getRegulatoryLocation", "()Ljava/util/Optional;",
&getRegulatoryLocation);
SuccessOrExit(err);

jmethodID getKeypairDelegate;
err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getKeypairDelegate",
"()Lchip/devicecontroller/KeypairDelegate;", &getKeypairDelegate);
Expand Down Expand Up @@ -345,6 +355,8 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr
bool attemptNetworkScanThread = env->CallBooleanMethod(controllerParams, getAttemptNetworkScanThread);
bool skipCommissioningComplete = env->CallBooleanMethod(controllerParams, getSkipCommissioningComplete);
uint64_t adminSubject = env->CallLongMethod(controllerParams, getAdminSubject);
jobject countryCodeOptional = env->CallObjectMethod(controllerParams, getCountryCode);
jobject regulatoryLocationOptional = env->CallObjectMethod(controllerParams, getRegulatoryLocation);

#ifdef JAVA_MATTER_CONTROLLER_TEST
std::unique_ptr<chip::Controller::ExampleOperationalCredentialsIssuer> opCredsIssuer(
Expand Down Expand Up @@ -384,6 +396,54 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr
SuccessOrExit(err);
}
}

jobject countryCode;
err = chip::JniReferences::GetInstance().GetOptionalValue(countryCodeOptional, countryCode);
SuccessOrExit(err);

if (countryCode != nullptr)
{
jstring countryCodeStr = static_cast<jstring>(countryCode);
JniUtfString countryCodeJniString(env, countryCodeStr);

VerifyOrExit(countryCodeJniString.size() == 2, err = CHIP_ERROR_INVALID_ARGUMENT);

chip::Controller::CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters();
commissioningParams.SetCountryCode(countryCodeJniString.charSpan());

// The wrapper internally has reserved storage for the country code and will copy the value.
err = wrapper->UpdateCommissioningParameters(commissioningParams);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "UpdateCommissioningParameters failed. Err = %" CHIP_ERROR_FORMAT, err.Format());
SuccessOrExit(err);
}
}

jobject regulatoryLocation;
err = chip::JniReferences::GetInstance().GetOptionalValue(regulatoryLocationOptional, regulatoryLocation);
SuccessOrExit(err);

if (regulatoryLocation != nullptr)
{
using namespace app::Clusters::GeneralCommissioning;

jint regulatoryLocationJint = chip::JniReferences::GetInstance().IntegerToPrimitive(regulatoryLocation);
VerifyOrExit(chip::CanCastTo<RegulatoryLocationType>(regulatoryLocationJint), err = CHIP_ERROR_INVALID_ARGUMENT);

RegulatoryLocationType regulatoryLocationType = static_cast<RegulatoryLocationType>(regulatoryLocationJint);
VerifyOrExit(regulatoryLocationType >= RegulatoryLocationType::kIndoor, err = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(regulatoryLocationType <= RegulatoryLocationType::kIndoorOutdoor, err = CHIP_ERROR_INVALID_ARGUMENT);

chip::Controller::CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters();
commissioningParams.SetDeviceRegulatoryLocation(regulatoryLocationType);
err = wrapper->UpdateCommissioningParameters(commissioningParams);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "UpdateCommissioningParameters failed. Err = %" CHIP_ERROR_FORMAT, err.Format());
SuccessOrExit(err);
}
}
}

// Create and start the IO thread. Must be called after Controller()->Init
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package chip.devicecontroller;

import java.util.Optional;
import javax.annotation.Nullable;

/** Parameters representing initialization arguments for {@link ChipDeviceController}. */
Expand All @@ -13,6 +14,8 @@ public final class ControllerParams {
private final boolean attemptNetworkScanWiFi;
private final boolean attemptNetworkScanThread;
private final boolean skipCommissioningComplete;
private final Optional<String> countryCode;
private final Optional<Integer> regulatoryLocationType;
@Nullable private final KeypairDelegate keypairDelegate;
@Nullable private final byte[] rootCertificate;
@Nullable private final byte[] intermediateCertificate;
Expand All @@ -32,6 +35,8 @@ private ControllerParams(Builder builder) {
this.attemptNetworkScanWiFi = builder.attemptNetworkScanWiFi;
this.attemptNetworkScanThread = builder.attemptNetworkScanThread;
this.skipCommissioningComplete = builder.skipCommissioningComplete;
this.countryCode = builder.countryCode;
this.regulatoryLocationType = builder.regulatoryLocationType;
this.keypairDelegate = builder.keypairDelegate;
this.rootCertificate = builder.rootCertificate;
this.intermediateCertificate = builder.intermediateCertificate;
Expand Down Expand Up @@ -73,6 +78,14 @@ public boolean getSkipCommissioningComplete() {
return skipCommissioningComplete;
}

public Optional<String> getCountryCode() {
return countryCode;
}

public Optional<Integer> getRegulatoryLocation() {
return regulatoryLocationType;
}

public KeypairDelegate getKeypairDelegate() {
return keypairDelegate;
}
Expand Down Expand Up @@ -126,6 +139,8 @@ public static class Builder {
private boolean attemptNetworkScanWiFi = false;
private boolean attemptNetworkScanThread = false;
private boolean skipCommissioningComplete = false;
private Optional<String> countryCode = Optional.empty();
private Optional<Integer> regulatoryLocationType = Optional.empty();
@Nullable private KeypairDelegate keypairDelegate = null;
@Nullable private byte[] rootCertificate = null;
@Nullable private byte[] intermediateCertificate = null;
Expand Down Expand Up @@ -247,6 +262,46 @@ public Builder setSkipCommissioningComplete(boolean skipCommissioningComplete) {
return this;
}

/**
* Sets the Regulatory Location country code passed to ChipDeviceCommissioner's
* CommissioningParameters.
*
* <p>Setting the country code will set the CountryCode when the SetRegulatoryConfig command is
* sent by this ChipDeviceCommissioner.
*
* @param countryCode an ISO 3166-1 alpha-2 code to represent the country, dependent territory,
* or special area of geographic interest
* @return
*/
public Builder setCountryCode(final String countryCode) {
if (countryCode == null || countryCode.length() != 2) {
throw new IllegalArgumentException("countryCode must be 2 characters");
}
this.countryCode = Optional.of(countryCode);
return this;
}

/**
* Sets the Regulatory Location capability passed to ChipDeviceCommissioner's
* CommissioningParameters.
*
* <p>Setting the regulatory location type will set the NewRegulatoryConfig when the
* SetRegulatoryConfig command is sent by this ChipDeviceCommissioner.
*
* @param regulatoryLocation an app::Clusters::GeneralCommissioning::RegulatoryLocationType enum
* value
* @return
*/
public Builder setRegulatoryLocation(int regulatoryLocation) {
if ((regulatoryLocation < 0) || (regulatoryLocation > 2)) {
throw new IllegalArgumentException(
"regulatoryLocation value must be between RegulatoryLocationType::kIndoor and "
+ "RegulatoryLocationType::kIndoorOutdoor");
}
this.regulatoryLocationType = Optional.of(regulatoryLocation);
return this;
}

public Builder setKeypairDelegate(KeypairDelegate keypairDelegate) {
this.keypairDelegate = keypairDelegate;
return this;
Expand Down

0 comments on commit ae8377c

Please sign in to comment.