Skip to content

Commit dcf35f1

Browse files
Merge branch 'master' into fix/python-subscripiton
2 parents 20046dd + 177d875 commit dcf35f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1708
-239
lines changed

.github/workflows/java-tests.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,17 @@ jobs:
132132
--tool-cluster "im" \
133133
--tool-args "onnetwork-long-im-invoke --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \
134134
--factoryreset \
135+
'
136+
- name: Run IM Batch Invoke Test
137+
run: |
138+
scripts/run_in_python_env.sh out/venv \
139+
'./scripts/tests/run_java_test.py \
140+
--app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app \
141+
--app-args "--discriminator 3840 --interface-id -1" \
142+
--tool-path out/linux-x64-java-matter-controller \
143+
--tool-cluster "im" \
144+
--tool-args "onnetwork-long-im-batch-invoke --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \
145+
--factoryreset \
135146
'
136147
- name: Run IM Read Test
137148
run: |

.github/workflows/lint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ jobs:
203203
# TODO: TLVDebug should ideally not be excluded here.
204204
# TODO: protocol_decoder.cpp should ideally not be excluded here.
205205
# TODO: PersistentStorageMacros.h should ideally not be excluded here.
206-
git grep -I -n "PRI.64" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)examples/chip-tool' ':(exclude)examples/tv-casting-app' ':(exclude)src/app/MessageDef/MessageDefHelper.cpp' ':(exclude)src/app/tests/integration/chip_im_initiator.cpp' ':(exclude)src/lib/core/TLVDebug.cpp' ':(exclude)src/lib/dnssd/tests/TestTxtFields.cpp' ':(exclude)src/lib/format/protocol_decoder.cpp' ':(exclude)src/lib/support/PersistentStorageMacros.h' ':(exclude)src/messaging/tests/echo/echo_requester.cpp' ':(exclude)src/platform/Linux' ':(exclude)src/platform/Ameba' ':(exclude)src/platform/ESP32' ':(exclude)src/platform/webos' ':(exclude)zzz_generated/chip-tool' ':(exclude)src/tools/chip-cert/Cmd_PrintCert.cpp' && exit 1 || exit 0
206+
git grep -I -n "PRI.64" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)examples/chip-tool' ':(exclude)examples/tv-casting-app' ':(exclude)src/app/MessageDef/MessageDefHelper.cpp' ':(exclude)src/app/tests/integration/chip_im_initiator.cpp' ':(exclude)src/lib/core/TLVDebug.cpp' ':(exclude)src/lib/dnssd/tests/TestTxtFields.cpp' ':(exclude)src/lib/format/protocol_decoder.cpp' ':(exclude)src/lib/support/PersistentStorageMacros.h' ':(exclude)src/messaging/tests/echo/echo_requester.cpp' ':(exclude)src/platform/Linux' ':(exclude)src/platform/Ameba' ':(exclude)src/platform/ESP32' ':(exclude)src/platform/Darwin' ':(exclude)src/darwin' ':(exclude)src/platform/webos' ':(exclude)zzz_generated/chip-tool' ':(exclude)src/tools/chip-cert/Cmd_PrintCert.cpp' && exit 1 || exit 0
207207
208208
# git grep exits with 0 if it finds a match, but we want
209209
# to fail (exit nonzero) on match. And we want to exclude this file,

examples/java-matter-controller/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ kotlin_binary("java-matter-controller") {
5757
"java/src/com/matter/controller/commands/pairing/PairOnNetworkFabricCommand.kt",
5858
"java/src/com/matter/controller/commands/pairing/PairOnNetworkInstanceNameCommand.kt",
5959
"java/src/com/matter/controller/commands/pairing/PairOnNetworkLongCommand.kt",
60+
"java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImExtendableInvokeCommand.kt",
6061
"java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImInvokeCommand.kt",
6162
"java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt",
6263
"java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt",

examples/java-matter-controller/java/src/com/matter/controller/Main.kt

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ private fun getImCommands(
6767
PairOnNetworkLongImSubscribeCommand(controller, credentialsIssuer),
6868
PairOnNetworkLongImWriteCommand(controller, credentialsIssuer),
6969
PairOnNetworkLongImInvokeCommand(controller, credentialsIssuer),
70+
PairOnNetworkLongImExtendableInvokeCommand(controller, credentialsIssuer),
7071
)
7172
}
7273

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* Copyright (c) 2024 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
package com.matter.controller.commands.pairing
19+
20+
import chip.devicecontroller.ChipDeviceController
21+
import chip.devicecontroller.ExtendableInvokeCallback
22+
import chip.devicecontroller.GetConnectedDeviceCallbackJni.GetConnectedDeviceCallback
23+
import chip.devicecontroller.model.InvokeElement
24+
import chip.devicecontroller.model.InvokeResponseData
25+
import chip.devicecontroller.model.NoInvokeResponseData
26+
import chip.devicecontroller.model.Status
27+
import com.matter.controller.commands.common.CredentialsIssuer
28+
import java.util.logging.Level
29+
import java.util.logging.Logger
30+
import kotlin.UShort
31+
import matter.tlv.AnonymousTag
32+
import matter.tlv.ContextSpecificTag
33+
import matter.tlv.TlvWriter
34+
35+
class PairOnNetworkLongImExtendableInvokeCommand(
36+
controller: ChipDeviceController,
37+
credsIssue: CredentialsIssuer?
38+
) :
39+
PairingCommand(
40+
controller,
41+
"onnetwork-long-im-batch-invoke",
42+
credsIssue,
43+
PairingModeType.ON_NETWORK,
44+
PairingNetworkType.NONE,
45+
DiscoveryFilterType.LONG_DISCRIMINATOR
46+
) {
47+
private var devicePointer: Long = 0
48+
49+
private fun setDevicePointer(devicePointer: Long) {
50+
this.devicePointer = devicePointer
51+
}
52+
53+
private inner class InternalInvokeCallback : ExtendableInvokeCallback {
54+
private var responseCount = 0
55+
56+
override fun onError(e: Exception) {
57+
logger.log(Level.INFO, "Batch Invoke receive onError" + e.message)
58+
setFailure("invoke failure")
59+
}
60+
61+
override fun onResponse(invokeResponseData: InvokeResponseData) {
62+
logger.log(Level.INFO, "Batch Invoke receive OnResponse on $invokeResponseData")
63+
val clusterId = invokeResponseData.getClusterId().getId()
64+
val commandId = invokeResponseData.getCommandId().getId()
65+
val tlvData = invokeResponseData.getTlvByteArray()
66+
val jsonData = invokeResponseData.getJsonString()
67+
val status = invokeResponseData.getStatus()
68+
69+
if (clusterId == CLUSTER_ID_IDENTIFY && commandId == IDENTIFY_COMMAND) {
70+
if (tlvData != null || jsonData != null) {
71+
setFailure("invoke failure with problematic payload")
72+
}
73+
if (
74+
status != null && status.status != Status.Code.Success && status.clusterStatus.isPresent()
75+
) {
76+
setFailure("invoke failure with incorrect status")
77+
}
78+
}
79+
80+
if (clusterId == CLUSTER_ID_TEST && commandId == TEST_ADD_ARGUMENT_RSP_COMMAND) {
81+
if (tlvData == null || jsonData == null) {
82+
setFailure("invoke failure with problematic payload")
83+
}
84+
85+
if (!jsonData.equals("""{"0:UINT":2}""")) {
86+
setFailure("invoke failure with problematic json")
87+
}
88+
89+
if (status != null) {
90+
setFailure("invoke failure with incorrect status")
91+
}
92+
}
93+
responseCount++
94+
}
95+
96+
override fun onNoResponse(noInvokeResponseData: NoInvokeResponseData) {
97+
logger.log(Level.INFO, "Batch Invoke receive onNoResponse on $noInvokeResponseData")
98+
}
99+
100+
override fun onDone() {
101+
if (responseCount == TEST_COMMONDS_NUM) {
102+
setSuccess()
103+
} else {
104+
setFailure("invoke failure")
105+
}
106+
}
107+
}
108+
109+
private inner class InternalGetConnectedDeviceCallback : GetConnectedDeviceCallback {
110+
override fun onDeviceConnected(devicePointer: Long) {
111+
setDevicePointer(devicePointer)
112+
logger.log(Level.INFO, "onDeviceConnected")
113+
}
114+
115+
override fun onConnectionFailure(nodeId: Long, error: Exception) {
116+
logger.log(Level.INFO, "onConnectionFailure")
117+
}
118+
}
119+
120+
override fun runCommand() {
121+
val number: UShort = 1u
122+
val tlvWriter1 = TlvWriter()
123+
tlvWriter1.startStructure(AnonymousTag)
124+
tlvWriter1.put(ContextSpecificTag(0), number)
125+
tlvWriter1.endStructure()
126+
127+
val element1: InvokeElement =
128+
InvokeElement.newInstance(
129+
/* endpointId= */ 0,
130+
CLUSTER_ID_IDENTIFY,
131+
IDENTIFY_COMMAND,
132+
tlvWriter1.getEncoded(),
133+
null
134+
)
135+
136+
val tlvWriter2 = TlvWriter()
137+
tlvWriter2.startStructure(AnonymousTag)
138+
tlvWriter2.put(ContextSpecificTag(0), number)
139+
tlvWriter2.put(ContextSpecificTag(1), number)
140+
tlvWriter2.endStructure()
141+
142+
val element2: InvokeElement =
143+
InvokeElement.newInstance(
144+
/* endpointId= */ 1,
145+
CLUSTER_ID_TEST,
146+
TEST_ADD_ARGUMENT_COMMAND,
147+
tlvWriter2.getEncoded(),
148+
null
149+
)
150+
151+
val invokeList = listOf(element1, element2)
152+
currentCommissioner()
153+
.pairDeviceWithAddress(
154+
getNodeId(),
155+
getRemoteAddr().address.hostAddress,
156+
MATTER_PORT,
157+
getDiscriminator(),
158+
getSetupPINCode(),
159+
null
160+
)
161+
currentCommissioner().setCompletionListener(this)
162+
waitCompleteMs(getTimeoutMillis())
163+
currentCommissioner()
164+
.getConnectedDevicePointer(getNodeId(), InternalGetConnectedDeviceCallback())
165+
clear()
166+
currentCommissioner()
167+
.extendableInvoke(InternalInvokeCallback(), devicePointer, invokeList, 0, 0)
168+
waitCompleteMs(getTimeoutMillis())
169+
}
170+
171+
companion object {
172+
private val logger =
173+
Logger.getLogger(PairOnNetworkLongImExtendableInvokeCommand::class.java.name)
174+
175+
private const val MATTER_PORT = 5540
176+
private const val CLUSTER_ID_IDENTIFY = 0x0003L
177+
private const val IDENTIFY_COMMAND = 0L
178+
private const val CLUSTER_ID_TEST = 0xFFF1FC05L
179+
private const val TEST_ADD_ARGUMENT_COMMAND = 0X04L
180+
private const val TEST_ADD_ARGUMENT_RSP_COMMAND = 0X01L
181+
private const val TEST_COMMONDS_NUM = 2
182+
}
183+
}

kotlin-detect-config.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ style:
104104
- "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkInstanceNameCommand.kt"
105105
- "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongCommand.kt"
106106
- "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImInvokeCommand.kt"
107+
- "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImExtendableInvokeCommand.kt"
107108
- "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt"
108109
- "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkShortCommand.kt"
109110
- "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkVendorCommand.kt"

scripts/tests/java/im_test.py

+13
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ def TestCmdOnnetworkLongImInvoke(self, nodeid, setuppin, discriminator, timeout)
7171
DumpProgramOutputToQueue(self.thread_list, Fore.GREEN + "JAVA " + Style.RESET_ALL, java_process, self.queue)
7272
return java_process.wait()
7373

74+
def TestCmdOnnetworkLongImExtendableInvoke(self, nodeid, setuppin, discriminator, timeout):
75+
java_command = self.command + ['im', 'onnetwork-long-im-batch-invoke', nodeid, setuppin, discriminator, timeout]
76+
logging.info(f"Execute: {java_command}")
77+
java_process = subprocess.Popen(
78+
java_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
79+
DumpProgramOutputToQueue(self.thread_list, Fore.GREEN + "JAVA " + Style.RESET_ALL, java_process, self.queue)
80+
return java_process.wait()
81+
7482
def TestCmdOnnetworkLongImWrite(self, nodeid, setuppin, discriminator, timeout):
7583
java_command = self.command + ['im', 'onnetwork-long-im-write', nodeid, setuppin, discriminator, timeout]
7684
logging.info(f"Execute: {java_command}")
@@ -101,6 +109,11 @@ def RunTest(self):
101109
code = self.TestCmdOnnetworkLongImInvoke(self.nodeid, self.setup_pin_code, self.discriminator, self.timeout)
102110
if code != 0:
103111
raise Exception(f"Testing pairing onnetwork-long-im-invoke failed with error {code}")
112+
elif self.command_name == 'onnetwork-long-im-batch-invoke':
113+
logging.info("Testing pairing onnetwork-long-im-batch-invoke")
114+
code = self.TestCmdOnnetworkLongImExtendableInvoke(self.nodeid, self.setup_pin_code, self.discriminator, self.timeout)
115+
if code != 0:
116+
raise Exception(f"Testing pairing onnetwork-long-im-batch-invoke failed with error {code}")
104117
elif self.command_name == 'onnetwork-long-im-write':
105118
logging.info("Testing pairing onnetwork-long-im-write")
106119
code = self.TestCmdOnnetworkLongImWrite(self.nodeid, self.setup_pin_code, self.discriminator, self.timeout)

src/app/clusters/on-off-server/on-off-server.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,15 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl
214214
ScenesManagement::ScenesServer::Instance().IsHandlerRegistered(endpoint, LevelControlServer::GetSceneHandler())))
215215
#endif
216216
{
217+
VerifyOrReturnError(mTransitionTimeInterface.sceneEventControl(endpoint) != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
217218
OnOffServer::Instance().scheduleTimerCallbackMs(mTransitionTimeInterface.sceneEventControl(endpoint), timeMs);
218219
}
219220

220221
return CHIP_NO_ERROR;
221222
}
222223

223224
private:
224-
OnOffTransitionTimeInterface mTransitionTimeInterface = OnOffTransitionTimeInterface(Attributes::OnOff::Id, sceneOnOffCallback);
225+
OnOffTransitionTimeInterface mTransitionTimeInterface = OnOffTransitionTimeInterface(OnOff::Id, sceneOnOffCallback);
225226
};
226227
static DefaultOnOffSceneHandler sOnOffSceneHandler;
227228

src/controller/AutoCommissioner.cpp

+6-21
Original file line numberDiff line numberDiff line change
@@ -673,20 +673,10 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio
673673
{
674674
CompletionStatus completionStatus;
675675
completionStatus.err = err;
676-
677-
if (err == CHIP_NO_ERROR)
678-
{
679-
ChipLogProgress(Controller, "Successfully finished commissioning step '%s'", StageToString(report.stageCompleted));
680-
}
681-
else
682-
{
683-
ChipLogProgress(Controller, "Error on commissioning step '%s': '%s'", StageToString(report.stageCompleted), err.AsString());
684-
}
685-
686676
if (err != CHIP_NO_ERROR)
687677
{
678+
ChipLogError(Controller, "Error on commissioning step '%s': '%s'", StageToString(report.stageCompleted), err.AsString());
688679
completionStatus.failedStage = MakeOptional(report.stageCompleted);
689-
ChipLogError(Controller, "Failed to perform commissioning step %d", static_cast<int>(report.stageCompleted));
690680
if (report.Is<AttestationErrorInfo>())
691681
{
692682
completionStatus.attestationResult = MakeOptional(report.Get<AttestationErrorInfo>().attestationResult);
@@ -727,19 +717,14 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio
727717
}
728718
else
729719
{
720+
ChipLogProgress(Controller, "Successfully finished commissioning step '%s'", StageToString(report.stageCompleted));
730721
switch (report.stageCompleted)
731722
{
732723
case CommissioningStage::kReadCommissioningInfo:
733724
break;
734725
case CommissioningStage::kReadCommissioningInfo2: {
735-
if (!report.Is<ReadCommissioningInfo>())
736-
{
737-
ChipLogError(Controller,
738-
"[BUG] Should read commissioning info, but report is not ReadCommissioningInfo. THIS IS A BUG.");
739-
}
740-
ReadCommissioningInfo commissioningInfo = report.Get<ReadCommissioningInfo>();
741-
742726
mDeviceCommissioningInfo = report.Get<ReadCommissioningInfo>();
727+
743728
if (!mParams.GetFailsafeTimerSeconds().HasValue() && mDeviceCommissioningInfo.general.recommendedFailsafe > 0)
744729
{
745730
mParams.SetFailsafeTimerSeconds(mDeviceCommissioningInfo.general.recommendedFailsafe);
@@ -751,11 +736,11 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio
751736
// Don't send DST unless the device says it needs it
752737
mNeedsDST = false;
753738

754-
mParams.SetSupportsConcurrentConnection(commissioningInfo.supportsConcurrentConnection);
739+
mParams.SetSupportsConcurrentConnection(mDeviceCommissioningInfo.supportsConcurrentConnection);
755740

756741
if (mParams.GetCheckForMatchingFabric())
757742
{
758-
chip::NodeId nodeId = commissioningInfo.remoteNodeId;
743+
chip::NodeId nodeId = mDeviceCommissioningInfo.remoteNodeId;
759744
if (nodeId != kUndefinedNodeId)
760745
{
761746
mParams.SetRemoteNodeId(nodeId);
@@ -764,7 +749,7 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio
764749

765750
if (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore)
766751
{
767-
if (commissioningInfo.icd.isLIT && commissioningInfo.icd.checkInProtocolSupport)
752+
if (mDeviceCommissioningInfo.icd.isLIT && mDeviceCommissioningInfo.icd.checkInProtocolSupport)
768753
{
769754
mNeedIcdRegistration = true;
770755
ChipLogDetail(Controller, "AutoCommissioner: ICD supports the check-in protocol.");

0 commit comments

Comments
 (0)