Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added RegulatoryConfig support to AutoCommissioner for Android #24413

Merged
merged 1 commit into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
tcarmelveilleux marked this conversation as resolved.
Show resolved Hide resolved

// 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);
swan-amazon marked this conversation as resolved.
Show resolved Hide resolved
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);
swan-amazon marked this conversation as resolved.
Show resolved Hide resolved
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);
swan-amazon marked this conversation as resolved.
Show resolved Hide resolved
return this;
}

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