Skip to content

Commit

Permalink
[Android] Remove TLV Decode / encode API in ChipTool (#28767)
Browse files Browse the repository at this point in the history
* Support JSON in Android ChipTool

* restyle kotlin

* Fix build error

* Check isEndOfTlv in ArrayValue

* Add kotlin exclude codeing check

* Add TestData in Android ChipTool

* Move TlvReader toAny method to ChipTool

* rollback tlvtoJson class

* rollback json test

* Update kotlin codestyle
  • Loading branch information
joonhaengHeo authored and pull[bot] committed Feb 8, 2024
1 parent 4f88d5f commit 2fe0875
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import chip.devicecontroller.model.AttributeWriteRequest
import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.NodeState
import chip.tlv.AnonymousTag
import chip.tlv.TlvReader
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.BasicClientFragmentBinding
import com.google.chip.chiptool.util.TlvParseUtil
import com.google.chip.chiptool.util.toAny
import java.util.Optional
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -55,7 +58,7 @@ class BasicClientFragment : Fragment() {
// TODO : Need to be implement poj-to-tlv
sendWriteAttribute(
BasicInformation.Attribute.NodeLabel,
TlvParseUtil.encode(binding.nodeLabelEd.text.toString())
TlvWriter().put(AnonymousTag, binding.nodeLabelEd.text.toString()).getEncoded()
)
binding.nodeLabelEd.onEditorAction(EditorInfo.IME_ACTION_DONE)
}
Expand All @@ -65,7 +68,7 @@ class BasicClientFragment : Fragment() {
// TODO : Need to be implement poj-to-tlv
sendWriteAttribute(
BasicInformation.Attribute.Location,
TlvParseUtil.encode(binding.locationEd.text.toString())
TlvWriter().put(AnonymousTag, binding.locationEd.text.toString()).getEncoded()
)
binding.locationEd.onEditorAction(EditorInfo.IME_ACTION_DONE)
}
Expand All @@ -75,7 +78,7 @@ class BasicClientFragment : Fragment() {
// TODO : Need to be implement poj-to-tlv
sendWriteAttribute(
BasicInformation.Attribute.LocalConfigDisabled,
TlvParseUtil.encode(isChecked)
TlvWriter().put(AnonymousTag, isChecked).getEncoded()
)
}
}
Expand Down Expand Up @@ -150,13 +153,13 @@ class BasicClientFragment : Fragment() {
}

override fun onReport(nodeState: NodeState?) {
val value =
val tlv =
nodeState
?.getEndpointState(endpointId)
?.getClusterState(clusterId)
?.getAttributeState(attributeId)
?.value
?: "null"
?.tlv
val value = tlv?.let { TlvReader(it).toAny() }
Log.i(TAG, "[Read Success] $attributeName: $value")
showMessage("[Read Success] $attributeName: $value")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.NodeState
import chip.tlv.AnonymousTag
import chip.tlv.TlvReader
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.MultiAdminClientFragmentBinding
import com.google.chip.chiptool.util.toAny
import kotlinx.coroutines.*

class MultiAdminClientFragment : Fragment() {
Expand Down Expand Up @@ -209,13 +211,13 @@ class MultiAdminClientFragment : Fragment() {
deviceController.readAttributePath(
object : ReportCallback {
override fun onReport(nodeState: NodeState?) {
val value =
val tlv =
nodeState
?.getEndpointState(endpointId)
?.getClusterState(clusterId)
?.getAttributeState(attributeId)
?.value
?: "null"
?.tlv
val value = tlv?.let { TlvReader(it).toAny() }
Log.i(TAG, "read $attributeName: $value")
showMessage("read $attributeName: $value")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.NodeState
import chip.tlv.AnonymousTag
import chip.tlv.ContextSpecificTag
import chip.tlv.TlvReader
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.OnOffClientFragmentBinding
import com.google.chip.chiptool.util.TlvParseUtil
import com.google.chip.chiptool.util.toAny
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
Expand Down Expand Up @@ -116,13 +117,13 @@ class OnOffClientFragment : Fragment() {
}

override fun onReport(nodeState: NodeState?) {
val value =
val tlv =
nodeState
?.getEndpointState(endpointId)
?.getClusterState(clusterId)
?.getAttributeState(attributeId)
?.value
?: "null"
?.tlv
val value = tlv?.let { TlvReader(it).toAny() }
Log.v(TAG, "On/Off attribute value: $value")
showMessage("On/Off attribute value: $value")
}
Expand Down Expand Up @@ -201,7 +202,7 @@ class OnOffClientFragment : Fragment() {
?.tlv
?: return
// TODO : Need to be implement poj-to-tlv
val value = TlvParseUtil.decodeBoolean(tlv)
val value = TlvReader(tlv).getBool(AnonymousTag)
val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
val time = formatter.format(Calendar.getInstance(Locale.getDefault()).time)
val message = "Subscribed on/off value at $time: ${if (value) "ON" else "OFF"}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ChipStructs
import chip.devicecontroller.ChipTLVValueDecoder
import chip.devicecontroller.ClusterIDMapping.OperationalCredentials
import chip.devicecontroller.InvokeCallback
import chip.devicecontroller.ReportCallback
Expand All @@ -19,11 +17,13 @@ import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.NodeState
import chip.tlv.AnonymousTag
import chip.tlv.ContextSpecificTag
import chip.tlv.TlvReader
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.OpCredClientFragmentBinding
import com.google.chip.chiptool.util.toAny
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

Expand Down Expand Up @@ -115,44 +115,16 @@ class OpCredClientFragment : Fragment() {
}

override fun onReport(nodeState: NodeState?) {
val value =
nodeState
?.getEndpointState(endpointId)
?.getClusterState(clusterId)
?.getAttributeState(attributeId)
?.value
?: "null"
val tlv =
nodeState
?.getEndpointState(endpointId)
?.getClusterState(clusterId)
?.getAttributeState(attributeId)
?.tlv

if (tlv == null) {
Log.i(TAG, "OpCred $attributeName value: $value")
showMessage("OpCred $attributeName value: $value")
return
}

val attributePath = ChipAttributePath.newInstance(endpointId, clusterId, attributeId)
when (attribute) {
OperationalCredentials.Attribute.Fabrics -> {
val ret =
ChipTLVValueDecoder.decodeAttributeValue<
List<ChipStructs.OperationalCredentialsClusterFabricDescriptorStruct>
>(
attributePath,
tlv
)
Log.i(TAG, "OpCred $attributeName value: $value")
showMessage(ret.toString())
}
else -> {
Log.i(TAG, "OpCred $attributeName value: $value")
showMessage("OpCred $attributeName value: $value")
}
}
val value = tlv?.let { TlvReader(it).toAny() }
Log.i(TAG, "OpCred $attributeName value: $value")
showMessage("OpCred $attributeName value: $value")
}
},
devicePtr,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ import chip.devicecontroller.ReportCallback
import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.NodeState
import chip.tlv.AnonymousTag
import chip.tlv.TlvReader
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.SensorClientFragmentBinding
import com.google.chip.chiptool.util.DeviceIdUtil
import com.google.chip.chiptool.util.TlvParseUtil
import com.jjoe64.graphview.LabelFormatter
import com.jjoe64.graphview.Viewport
import com.jjoe64.graphview.series.DataPoint
Expand Down Expand Up @@ -224,7 +225,7 @@ class SensorClientFragment : Fragment() {
// TODO : Need to be implement poj-to-tlv
val value =
try {
TlvParseUtil.decodeInt(tlv)
TlvReader(tlv).getInt(AnonymousTag)
} catch (ex: Exception) {
showMessage(R.string.sensor_client_read_error_text, "value is null")
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.ChipPathId
import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.NodeState
import chip.jsontlv.putJsonString
import chip.tlv.AnonymousTag
import chip.tlv.ContextSpecificTag
import chip.tlv.TlvReader
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.WildcardFragmentBinding
import com.google.chip.chiptool.util.toAny
import java.lang.StringBuilder
import java.util.Optional
import kotlin.coroutines.resume
Expand Down Expand Up @@ -219,7 +220,8 @@ class WildcardFragment : Fragment() {
stringBuilder.append("\t${ChipIdLookup.clusterIdToName(clusterId)}Cluster: {\n")
clusterState.attributeStates.forEach { (attributeId, attributeState) ->
val attributeName = ChipIdLookup.attributeIdToName(clusterId, attributeId)
stringBuilder.append("\t\t$attributeName: ${attributeState.value}\n")
val tlv = attributeState.tlv
stringBuilder.append("\t\t$attributeName: ${TlvReader(tlv).toAny()}\n")
}
clusterState.eventStates.forEach { (eventId, events) ->
for (event in events) {
Expand All @@ -229,7 +231,8 @@ class WildcardFragment : Fragment() {
stringBuilder.append("\t\ttimestampValue: ${event.timestampValue}\n")

val eventName = ChipIdLookup.eventIdToName(clusterId, eventId)
stringBuilder.append("\t\t$eventName: ${event.value}\n")
val tlv = event.tlv
stringBuilder.append("\t\t$eventName: ${TlvReader(tlv).toAny()}\n")
}
}
stringBuilder.append("\t}\n")
Expand Down Expand Up @@ -305,19 +308,6 @@ class WildcardFragment : Fragment() {
val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString())
val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString())
val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString())
val tlvWriter = TlvWriter()
val values = writeValue.split(",")

if (values.size > 1) tlvWriter.startArray(AnonymousTag)
for (value in values) {
try {
TLV_MAP[writeValueType]?.generate(tlvWriter, value.trim())
} catch (ex: Exception) {
Log.e(TAG, "Invalid Data Type", ex)
return
}
}
if (values.size > 1) tlvWriter.endArray()

val version =
if (dataVersion == null) {
Expand All @@ -326,14 +316,36 @@ class WildcardFragment : Fragment() {
Optional.of(dataVersion)
}

val writeRequest =
AttributeWriteRequest.newInstance(
endpointId,
clusterId,
attributeId,
tlvWriter.getEncoded(),
version
)
lateinit var writeRequest: AttributeWriteRequest

if (writeValueType == "json") {
writeRequest =
AttributeWriteRequest.newInstance(endpointId, clusterId, attributeId, writeValue, version)
} else {
val tlvWriter = TlvWriter()
val values = writeValue.split(",")

if (values.size > 1) tlvWriter.startArray(AnonymousTag)
for (value in values) {
try {
TLV_MAP[writeValueType]?.generate(tlvWriter, value.trim())
} catch (ex: Exception) {
Log.e(TAG, "Invalid Data Type", ex)
return
}
}
if (values.size > 1) tlvWriter.endArray()

writeRequest =
AttributeWriteRequest.newInstance(
endpointId,
clusterId,
attributeId,
tlvWriter.getEncoded(),
version
)
}

deviceController.write(
writeAttributeCallback,
ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId),
Expand All @@ -343,35 +355,14 @@ class WildcardFragment : Fragment() {
)
}

private suspend fun invoke(invokeField: String, timedRequestTimeoutMs: Int, imTimeoutMs: Int) {
private suspend fun invoke(invokeJson: String, timedRequestTimeoutMs: Int, imTimeoutMs: Int) {
val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString())
val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString())
val commandId = getChipPathIdForText(binding.commandIdEd.text.toString())

val tlvWriter = TlvWriter()
val fields =
if (invokeField.isEmpty()) {
listOf()
} else {
invokeField.split(",")
}
var count = 0
tlvWriter.startStructure(AnonymousTag)
for (field in fields) {
try {
val type = field.split(":")[0]
val value = field.split(":")[1]

Log.d(TAG, "value : $type - $value")
TLV_MAP[type]?.generate(tlvWriter, value.trim(), ContextSpecificTag(count++))
} catch (ex: Exception) {
Log.e(TAG, "Invalid value", ex)
return
}
}
tlvWriter.endStructure()
val jsonString = invokeJson.ifEmpty { "{}" }
val invokeElement =
InvokeElement.newInstance(endpointId, clusterId, commandId, tlvWriter.getEncoded(), null)
InvokeElement.newInstance(endpointId, clusterId, commandId, null, jsonString)
deviceController.invoke(
invokeCallback,
ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId),
Expand Down Expand Up @@ -652,6 +643,12 @@ class WildcardFragment : Fragment() {

private val TLV_MAP =
mapOf(
"json" to
object : TlvWriterInterface {
override fun generate(writer: TlvWriter, value: String, tag: chip.tlv.Tag) {
writer.putJsonString(tag, value)
}
},
"UnsignedInt" to
object : TlvWriterInterface {
override fun generate(writer: TlvWriter, value: String, tag: chip.tlv.Tag) {
Expand Down
Loading

0 comments on commit 2fe0875

Please sign in to comment.