From 1029404b7e2d39b057802a32a34f933157a92918 Mon Sep 17 00:00:00 2001 From: "tianfeng.yang" <130436698+tianfeng-yang@users.noreply.github.com> Date: Fri, 9 Feb 2024 04:57:58 +0800 Subject: [PATCH] [Python] CommissonWithCode support discoveryType (#31904) * [Linux] fix memory leak * [Python] call StopDiscovery after DiscoveryNodes * [Python] CommissionWithCode support DiscoveryType * fix param error * add e2e test * automatically run in CI * Test different modes using different devices * fix error manual code --- .../ChipDeviceController-ScriptBinding.cpp | 10 ++-- src/controller/python/chip/ChipDeviceCtrl.py | 7 ++- .../python/chip/discovery/__init__.py | 6 ++ .../python/test/test_scripts/base.py | 4 +- .../test/test_scripts/commissioning_test.py | 13 ++++- .../linux-cirque/CommissioningTest.py | 58 ++++++++++++++++++- 6 files changed, 84 insertions(+), 14 deletions(-) diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index b8d95292770d71..2576a360307611 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -137,7 +137,7 @@ PyChipError pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissio PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr, uint32_t setupPINCode, chip::NodeId nodeid); PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload, - chip::NodeId nodeid, bool networkOnly); + chip::NodeId nodeid, uint8_t discoveryType); PyChipError pychip_DeviceController_UnpairDevice(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId remoteDeviceId, DeviceUnpairingCompleteFunct callback); PyChipError pychip_DeviceController_SetThreadOperationalDataset(const char * threadOperationalDataset, uint32_t size); @@ -401,13 +401,11 @@ PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommission } PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload, - chip::NodeId nodeid, bool networkOnly) + chip::NodeId nodeid, uint8_t discoveryType) { - chip::Controller::DiscoveryType discoveryType = chip::Controller::DiscoveryType::kAll; sPairingDelegate.SetExpectingPairingComplete(true); - if (networkOnly) - discoveryType = chip::Controller::DiscoveryType::kDiscoveryNetworkOnly; - return ToPyChipError(devCtrl->PairDevice(nodeid, onboardingPayload, sCommissioningParameters, discoveryType)); + return ToPyChipError(devCtrl->PairDevice(nodeid, onboardingPayload, sCommissioningParameters, + static_cast(discoveryType))); } namespace { diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 509e6f5e247fcb..2297dfff3049ab 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -238,6 +238,7 @@ def attestationChallenge(self) -> bytes: DiscoveryFilterType = discovery.FilterType +DiscoveryType = discovery.DiscoveryType class ChipDeviceControllerBase(): @@ -1624,7 +1625,7 @@ def _InitLib(self): self._dmLib.pychip_DeviceController_ConnectIP.restype = PyChipError self._dmLib.pychip_DeviceController_ConnectWithCode.argtypes = [ - c_void_p, c_char_p, c_uint64, c_bool] + c_void_p, c_char_p, c_uint64, c_uint8] self._dmLib.pychip_DeviceController_ConnectWithCode.restype = PyChipError self._dmLib.pychip_DeviceController_UnpairDevice.argtypes = [ @@ -1937,7 +1938,7 @@ def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, return PyChipError(CHIP_ERROR_TIMEOUT) return self._ChipStack.commissioningEventRes - def CommissionWithCode(self, setupPayload: str, nodeid: int, networkOnly: bool = False) -> PyChipError: + def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType: DiscoveryType = DiscoveryType.DISCOVERY_ALL) -> PyChipError: ''' Commission with the given nodeid from the setupPayload. setupPayload may be a QR or manual code. ''' @@ -1953,7 +1954,7 @@ def CommissionWithCode(self, setupPayload: str, nodeid: int, networkOnly: bool = self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectWithCode( - self.devCtrl, setupPayload, nodeid, networkOnly) + self.devCtrl, setupPayload, nodeid, discoveryType.value) ) if not self._ChipStack.commissioningCompleteEvent.isSet(): # Error 50 is a timeout diff --git a/src/controller/python/chip/discovery/__init__.py b/src/controller/python/chip/discovery/__init__.py index ce27037dfbe499..c400d97542a69d 100644 --- a/src/controller/python/chip/discovery/__init__.py +++ b/src/controller/python/chip/discovery/__init__.py @@ -26,6 +26,12 @@ from chip.native import PyChipError +class DiscoveryType(enum.IntEnum): + DISCOVERY_NETWORK_ONLY = 0 + DISCOVERY_NETWORK_ONLY_WITHOUT_PASE_AUTO_RETRY = 1 + DISCOVERY_ALL = 2 + + class FilterType(enum.IntEnum): # These must match chip::Dnssd::DiscoveryFilterType values (barring the naming convention) NONE = 0 diff --git a/src/controller/python/test/test_scripts/base.py b/src/controller/python/test/test_scripts/base.py index 88f17de56f53a3..ed091858d289a8 100644 --- a/src/controller/python/test/test_scripts/base.py +++ b/src/controller/python/test/test_scripts/base.py @@ -341,9 +341,9 @@ def TestCommissioning(self, ip: str, setuppin: int, nodeid: int): self.logger.info("Commissioning finished.") return True - def TestCommissioningWithSetupPayload(self, setupPayload: str, nodeid: int): + def TestCommissioningWithSetupPayload(self, setupPayload: str, nodeid: int, discoveryType: int = 2): self.logger.info("Commissioning device with setup payload {}".format(setupPayload)) - if not self.devCtrl.CommissionWithCode(setupPayload, nodeid): + if not self.devCtrl.CommissionWithCode(setupPayload, nodeid, chip.discovery.DiscoveryType(discoveryType)): self.logger.info( "Failed to finish commissioning device {}".format(setupPayload)) return False diff --git a/src/controller/python/test/test_scripts/commissioning_test.py b/src/controller/python/test/test_scripts/commissioning_test.py index ca3ac311983d6d..b6adc0f477884d 100755 --- a/src/controller/python/test/test_scripts/commissioning_test.py +++ b/src/controller/python/test/test_scripts/commissioning_test.py @@ -39,6 +39,7 @@ # Network id, for the thread network, current a const value, will be changed to XPANID of the thread network. TEST_THREAD_NETWORK_ID = "fedcba9876543210" TEST_DISCRIMINATOR = 3840 +TEST_DISCOVERY_TYPE = 2 ENDPOINT_ID = 0 LIGHTING_ENDPOINT_ID = 1 @@ -104,6 +105,15 @@ def main(): help="Path that contains valid and trusted PAA Root Certificates.", metavar="" ) + optParser.add_option( + "--discovery-type", + action="store", + dest="discoveryType", + default=TEST_DISCOVERY_TYPE, + type=int, + help="Discovery type of commissioning. (0: networkOnly 1: networkOnlyWithoutPASEAutoRetry 2: All)", + metavar="" + ) (options, remainingArgs) = optParser.parse_args(sys.argv[1:]) @@ -129,7 +139,8 @@ def main(): elif options.setupPayload: logger.info("Testing commissioning (w/ Setup Payload)") FailIfNot(test.TestCommissioningWithSetupPayload(setupPayload=options.setupPayload, - nodeid=options.nodeid), + nodeid=options.nodeid, + discoveryType=options.discoveryType), "Failed to finish commissioning") else: TestFail("Must provide device address or setup payload to commissioning the device") diff --git a/src/test_driver/linux-cirque/CommissioningTest.py b/src/test_driver/linux-cirque/CommissioningTest.py index 463d24deeb9a05..d6cad0fb0303ec 100755 --- a/src/test_driver/linux-cirque/CommissioningTest.py +++ b/src/test_driver/linux-cirque/CommissioningTest.py @@ -38,6 +38,9 @@ TEST_EXTPANID = "fedcba9876543210" TEST_DISCRIMINATOR = 3840 TEST_DISCRIMINATOR2 = 3584 +TEST_DISCRIMINATOR3 = 1203 +TEST_DISCRIMINATOR4 = 2145 +TEST_DISCOVERY_TYPE = [0, 1, 2] MATTER_DEVELOPMENT_PAA_ROOT_CERTS = "credentials/development/paa-root-certs" DEVICE_CONFIG = { @@ -67,6 +70,24 @@ 'docker_network': 'Ipv6', 'traffic_control': {'latencyMs': 100}, "mount_pairs": [[CHIP_REPO, CHIP_REPO]], + }, + 'device3': { + 'type': 'CHIPEndDevice', + 'base_image': '@default', + 'capability': ['Thread', 'TrafficControl', 'Mount'], + 'rcp_mode': True, + 'docker_network': 'Ipv6', + 'traffic_control': {'latencyMs': 100}, + "mount_pairs": [[CHIP_REPO, CHIP_REPO]], + }, + 'device4': { + 'type': 'CHIPEndDevice', + 'base_image': '@default', + 'capability': ['Thread', 'TrafficControl', 'Mount'], + 'rcp_mode': True, + 'docker_network': 'Ipv6', + 'traffic_control': {'latencyMs': 100}, + "mount_pairs": [[CHIP_REPO, CHIP_REPO]], } } @@ -95,6 +116,10 @@ def run_controller_test(self): servers[0]['nodeid'] = 1 servers[1]['discriminator'] = TEST_DISCRIMINATOR2 servers[1]['nodeid'] = 2 + servers[2]['discriminator'] = TEST_DISCRIMINATOR3 + servers[2]['nodeid'] = 3 + servers[3]['discriminator'] = TEST_DISCRIMINATOR4 + servers[3]['nodeid'] = 4 for server in servers: self.execute_device_cmd( @@ -128,13 +153,42 @@ def run_controller_test(self): "Test failed: non-zero return code") command = ("gdb -return-child-result -q -ex run -ex bt --args python3 " - "{} -t 150 --paa-trust-store-path {} --discriminator {} --setup-payload {} --nodeid {}").format( + "{} -t 150 --paa-trust-store-path {} --discriminator {} --setup-payload {} --nodeid {} --discovery-type {}").format( os.path.join( CHIP_REPO, "src/controller/python/test/test_scripts/commissioning_test.py"), os.path.join(CHIP_REPO, MATTER_DEVELOPMENT_PAA_ROOT_CERTS), servers[1]['discriminator'], "33331712336", - servers[1]['nodeid']) + servers[1]['nodeid'], + TEST_DISCOVERY_TYPE[2]) + ret = self.execute_device_cmd(req_device_id, command) + + self.assertEqual(ret['return_code'], '0', + "Test failed: non-zero return code") + + command = ("gdb -return-child-result -q -ex run -ex bt --args python3 " + "{} -t 150 --paa-trust-store-path {} --discriminator {} --setup-payload {} --nodeid {} --discovery-type {}").format( + os.path.join( + CHIP_REPO, "src/controller/python/test/test_scripts/commissioning_test.py"), + os.path.join(CHIP_REPO, MATTER_DEVELOPMENT_PAA_ROOT_CERTS), + servers[2]['discriminator'], + "10054912339", + servers[2]['nodeid'], + TEST_DISCOVERY_TYPE[0]) + ret = self.execute_device_cmd(req_device_id, command) + + self.assertEqual(ret['return_code'], '0', + "Test failed: non-zero return code") + + command = ("gdb -return-child-result -q -ex run -ex bt --args python3 " + "{} -t 150 --paa-trust-store-path {} --discriminator {} --setup-payload {} --nodeid {} --discovery-type {}").format( + os.path.join( + CHIP_REPO, "src/controller/python/test/test_scripts/commissioning_test.py"), + os.path.join(CHIP_REPO, MATTER_DEVELOPMENT_PAA_ROOT_CERTS), + servers[3]['discriminator'], + "20054912334", + servers[3]['nodeid'], + TEST_DISCOVERY_TYPE[1]) ret = self.execute_device_cmd(req_device_id, command) self.assertEqual(ret['return_code'], '0',