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

Add initial kotlin setuppayload implementation #26676

Merged
merged 2 commits into from
May 23, 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
2 changes: 1 addition & 1 deletion examples/java-matter-controller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ java_library("java") {
output_name = "JavaMatterController.jar"
deps = [
"${chip_root}/src/controller/java",
"${chip_root}/src/setup_payload/java",
"${chip_root}/third_party/java_deps:annotation",
]

Expand All @@ -39,6 +38,7 @@ kotlin_binary("java-matter-controller") {
deps = [
":java",
"${chip_root}/src/controller/java:json_to_tlv_to_json_test",
"${chip_root}/src/controller/java:onboarding_payload",
"${chip_root}/src/controller/java:tlv_read_write_test",
"${chip_root}/src/controller/java:tlv_reader_test",
"${chip_root}/src/controller/java:tlv_writer_test",
Expand Down
2 changes: 1 addition & 1 deletion examples/java-matter-controller/Manifest.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Main-Class: com.matter.controller.MainKt
Class-Path: ../lib/third_party/connectedhomeip/src/controller/java/CHIPController.jar ../lib/third_party/connectedhomeip/src/setup_payload/java/SetupPayloadParser.jar ../lib/third_party/connectedhomeip/third_party/java_deps/stub_src/Android.jar ../lib/third_party/connectedhomeip/third_party/java_deps/json-20220924.jar ../lib/third_party/connectedhomeip/third_party/java_deps/jsr305-3.0.2.jar ../lib/third_party/connectedhomeip/third_party/java_deps/kotlin-stdlib-1.8.10.jar
Class-Path: ../lib/third_party/connectedhomeip/src/controller/java/CHIPController.jar ../lib/third_party/connectedhomeip/src/setup_payload/java/OnboardingPayload.jar ../lib/third_party/connectedhomeip/third_party/java_deps/stub_src/Android.jar ../lib/third_party/connectedhomeip/third_party/java_deps/json-20220924.jar ../lib/third_party/connectedhomeip/third_party/java_deps/jsr305-3.0.2.jar ../lib/third_party/connectedhomeip/third_party/java_deps/kotlin-stdlib-1.8.10.jar

35 changes: 34 additions & 1 deletion src/controller/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ kotlin_library("json_to_tlv_to_json_test") {

deps = [
":jsontlv",
":tlv",
"${chip_root}/third_party/java_deps:gson",
"${chip_root}/third_party/java_deps:junit-4",
"${chip_root}/third_party/java_deps:kotlin-test",
Expand All @@ -237,6 +236,40 @@ kotlin_library("json_to_tlv_to_json_test") {
kotlinc_flags = [ "-Xlint:deprecation" ]
}

shared_library("jni_for_onboarding_payload") {
output_name = "libOnboardingPayload"
if (build_java_matter_controller) {
include_dirs = java_matter_controller_dependent_paths
output_dir = "${root_out_dir}/lib/jni"
} else {
output_dir = "${root_out_dir}/lib/jni/${android_abi}"
}

sources = [ "OnboardingPayloadParser-JNI.cpp" ]

deps = [
"${chip_root}/src/lib",
"${chip_root}/src/setup_payload",
]
}

kotlin_library("onboarding_payload") {
output_name = "OnboardingPayload.jar"

data_deps = [ ":jni_for_onboarding_payload" ]

if (!build_java_matter_controller) {
data_deps += [ "${chip_root}/build/chip/java:shared_cpplib" ]
}

sources = [
"src/chip/onboardingpayload/DiscoveryCapability.kt",
"src/chip/onboardingpayload/OnboardingPayload.kt",
"src/chip/onboardingpayload/OnboardingPayloadParser.kt",
"src/chip/onboardingpayload/OptionalQRCodeInfo.kt",
]
}

android_library("java") {
output_name = "CHIPController.jar"

Expand Down
378 changes: 378 additions & 0 deletions src/controller/java/OnboardingPayloadParser-JNI.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package chip.onboardingpayload

/**
* Enum values for possible bits in the onboarding paylod's discovery capabilities bitmask.
*/
enum class DiscoveryCapability {
SOFT_AP,
BLE,
ON_NETWORK
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package chip.onboardingpayload

/** Class to hold the data from the scanned QR code or Manual Pairing Code. */
class OnboardingPayload(
/** Version info of the OnboardingPayload: version SHALL be 0 */
var version: Int = 0,

/** The CHIP device vendor ID: Vendor ID SHALL be between 1 and 0xFFF4. */
var vendorId: Int = 0,

/** The CHIP device product ID: Product ID SHALL BE greater than 0. */
var productId: Int = 0,

/** Commissioning flow: 0 = standard, 1 = requires user action, 2 = custom */
var commissioningFlow: Int = 0,

/**
* The CHIP device supported rendezvous flags: At least one DiscoveryCapability must be included.
*/
var discoveryCapabilities: Set<DiscoveryCapability> = emptySet(),

/** The CHIP device discriminator: */
var discriminator: Int = 0,

/**
* If hasShortDiscriminator is true, the discriminator value contains just the high 4 bits of the
* full discriminator. For example, if hasShortDiscriminator is true and discriminator is 0xA,
* then the full discriminator can be anything in the range 0xA00 to 0xAFF.
*/
var hasShortDiscriminator: Boolean = false,

/**
* The CHIP device setup PIN code: setupPINCode SHALL be greater than 0. Also invalid setupPINCode
* is {000000000, 11111111, 22222222, 33333333, 44444444, 55555555, 66666666, 77777777, 88888888,
* 99999999, 12345678, 87654321}.
*/
var setupPinCode: Long = 0
) {
var optionalQRCodeInfo: HashMap<Int, OptionalQRCodeInfo>

init {
optionalQRCodeInfo = HashMap()
}

constructor(
version: Int,
vendorId: Int,
productId: Int,
commissioningFlow: Int,
discoveryCapabilities: Set<DiscoveryCapability>,
discriminator: Int,
setupPinCode: Long
) : this(
version,
vendorId,
productId,
commissioningFlow,
discoveryCapabilities,
discriminator,
false,
setupPinCode
)

fun addOptionalQRCodeInfo(info: OptionalQRCodeInfo) {
optionalQRCodeInfo[info.tag] = info
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package chip.onboardingpayload

import java.util.logging.Level
import java.util.logging.Logger

/** Parser for scanned QR code or Manual Pairing Code. */
class OnboardingPayloadParser {
/**
* Returns [OnboardingPayload] parsed from the QR code string. If an invalid element is included
* in the QRCode Parse result, OnboardingPayloadException occurs. Refer to [OnboardingPayload] for the
* description of the invalid element.
*/
@Throws(UnrecognizedQrCodeException::class, OnboardingPayloadException::class)
fun parseQrCode(qrCodeString: String): OnboardingPayload {
return fetchPayloadFromQrCode(qrCodeString, false)
}

/**
* Returns [OnboardingPayload] parsed from the QR code string.
*
* @param qrCodeString the QRCode for commissioning device.
* @param skipPayloadValidation If this value is true, payload element validation is not checked.
* Consider saying that the payload must still parse correctly, but this skips validation of the
* content past parsing (i.e. it does not validate ranges for individual elements).
* Refer to [OnboardingPayload] for the description of the invalid element.
*/
@Throws(UnrecognizedQrCodeException::class, OnboardingPayloadException::class)
fun parseQrCode(qrCodeString: String, skipPayloadValidation: Boolean): OnboardingPayload {
return fetchPayloadFromQrCode(qrCodeString, skipPayloadValidation)
}

/**
* Returns [OnboardingPayload] parsed from the Manual Pairing Code string. If an SetupPINCode has
* invalid value, OnboardingPayloadException occurs. Refer to [OnboardingPayload] for the description
* of the invalid element.
*/
@Throws(InvalidManualPairingCodeFormatException::class, OnboardingPayloadException::class)
fun parseManualPairingCode(manualPairingCodeString: String): OnboardingPayload {
return parsePayloadFromManualPairingCode(manualPairingCodeString, false)
}

/**
* Returns [OnboardingPayload] parsed from the Manual Pairing Code string.
*
* @param manualPairingCodeString the manual Pairing Code for commissioning device.
* @param skipPayloadValidation If this value is true, payload element validation is not checked.
* Consider saying that the payload must still parse correctly, but this skips validation of the
* content past parsing (i.e. it does not validate ranges for individual elements).
* Refer to [OnboardingPayload] for the description of the invalid element.
*/
@Throws(InvalidManualPairingCodeFormatException::class, OnboardingPayloadException::class)
fun parseManualPairingCode(manualPairingCodeString: String, skipPayloadValidation: Boolean): OnboardingPayload {
return parsePayloadFromManualPairingCode(manualPairingCodeString, skipPayloadValidation)
}

/** Get QR code string from [OnboardingPayload]. */
@Throws(OnboardingPayloadException::class)
external fun getQrCodeFromPayload(payload: OnboardingPayload): String?

/** Get Manual Pairing Code string from [OnboardingPayload]. */
@Throws(OnboardingPayloadException::class)
external fun getManualPairingCodeFromPayload(payload: OnboardingPayload): String?

@Throws(UnrecognizedQrCodeException::class, OnboardingPayloadException::class)
private external fun fetchPayloadFromQrCode(
qrCodeString: String, skipPayloadValidation: Boolean
): OnboardingPayload

@Throws(InvalidManualPairingCodeFormatException::class, OnboardingPayloadException::class)
private external fun parsePayloadFromManualPairingCode(
manualPairingCodeString: String, skipPayloadValidation: Boolean
): OnboardingPayload

class UnrecognizedQrCodeException(qrCode: String) :
Exception(String.format("Invalid QR code string: %s", qrCode), null) {
companion object {
private const val serialVersionUID = 1L
}
}

class InvalidManualPairingCodeFormatException(manualPairingCode: String) :
Exception(String.format("Invalid format for manual pairing code string: %s", manualPairingCode), null) {
companion object {
private const val serialVersionUID = 1L
}
}

class OnboardingPayloadException(var errorCode: Int, message: String?) :
Exception(message ?: String.format("Error Code %d", errorCode)) {
companion object {
private const val serialVersionUID = 1L
}
}

companion object {
private val LOGGER: Logger = Logger.getLogger(OnboardingPayloadParser::class.java.getSimpleName())

init {
try {
System.loadLibrary("OnboardingPayload")
} catch (e: UnsatisfiedLinkError) {
LOGGER.log(Level.SEVERE, "Cannot load library.", e)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package chip.onboardingpayload

class OptionalQRCodeInfo {
enum class OptionalQRCodeInfoType {
TYPE_UNKNOWN,
TYPE_STRING,
TYPE_INT32,
TYPE_INT64,
TYPE_UINT32,
TYPE_UINT64
}

var tag = 0
var type: OptionalQRCodeInfoType? = null
var data: String? = null
var int32 = 0
}