Skip to content

Commit c65786a

Browse files
OlivierGrerestyled-commitsandy31415Copilot
authored
Add ConnectNFC to Python controller. (project-chip#41018)
* Add ConnectNFC to Python controller. * Renammed CommissionThread => CommissionBleThread Renammed CommissionWiFi => CommissionBleWiFi Added CommissionNfcThread. Added "nfc-thread" commissioning_method. * Added missing declaration. Change-Id: I54d6f9aa42d738aac604204f0b46c0bc575a79af * Modifications from Harshith Change-Id: Id382d1596d5fe6be7de8a62256ae163ca7f11ec6 * Restyled by autopep8 * Fixed Lint error Change-Id: I5ac188b29a4283a2d0731685c72fbacea7423e21 * Update scripts/build_python.sh Co-authored-by: Andrei Litvin <[email protected]> * Update src/controller/python/matter/ChipDeviceCtrl.py Co-authored-by: Copilot <[email protected]> * Update src/python_testing/matter_testing_infrastructure/matter/testing/commissioning.py Co-authored-by: Copilot <[email protected]> * Restyled by autopep8 * Fix error in PeerAddress constructor for NFC Transport. Change-Id: I6da2049be3bb8902dd7e7e179da863e6bc20e866 * Fixed copy paste error. Change-Id: I16ea3f9f6e9582b9f76b69ab21de52444fb55541 * Fix Change-Id: I812496268aa223cb4b42ccf9e594556228b43138 * Added supports_nfc_commissioning() Change-Id: Ide93134c42c69c24f43c10af366f436c9c2f4e7c * When doing NFC commissioning, only a long discriminator can be used. Change-Id: I88697b61140bdd138d4e7cce85f9dc9bbef22f3b --------- Co-authored-by: Restyled.io <[email protected]> Co-authored-by: Andrei Litvin <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 522655a commit c65786a

File tree

6 files changed

+103
-10
lines changed

6 files changed

+103
-10
lines changed

scripts/build_python.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ echo_bold_white() {
3737
CHIP_ROOT=$(_normpath "$(dirname "$0")/..")
3838

3939
declare enable_ble=true
40+
declare enable_nfc=true
4041
declare enable_ipv4=true
4142
declare wifi_paf_config=""
4243
declare chip_detail_logging=false
@@ -70,6 +71,7 @@ Input Options:
7071
By default it is $chip_detail_logging.
7172
-m, --chip_mdns ChipMDNSValue Specify ChipMDNSValue as platform or minimal.
7273
By default it is $chip_mdns.
74+
-n, --enable_nfc <true/false> Enable NFC in the controller (default=$enable_nfc)
7375
-w, --enable_webrtc <true/false> Enable WebRTC support in the controller (default=$enable_webrtc)
7476
-t --time_between_case_retries MRPActiveRetryInterval Specify MRPActiveRetryInterval value
7577
Default is 300 ms
@@ -108,6 +110,14 @@ while (($#)); do
108110
fi
109111
shift
110112
;;
113+
--enable_nfc | -n)
114+
enable_nfc=$2
115+
if [[ "$enable_nfc" != "true" && "$enable_nfc" != "false" ]]; then
116+
echo "Error: --enable_nfc/-n should have a true/false value, not '$enable_nfc'" >&2
117+
exit 1
118+
fi
119+
shift
120+
;;
111121
--enable_wifi_paf | -p)
112122
declare wifi_paf_arg="$2"
113123
if [[ "$wifi_paf_arg" != "true" && "$wifi_paf_arg" != "false" ]]; then
@@ -219,6 +229,7 @@ echo " chip_mdns=\"$chip_mdns\""
219229
echo " chip_case_retry_delta=\"$chip_case_retry_delta\""
220230
echo " pregen_dir=\"$pregen_dir\""
221231
echo " enable_ble=\"$enable_ble\""
232+
echo " enable_nfc=\"$enable_nfc\""
222233
if [[ -n $wifi_paf_config ]]; then
223234
echo " $wifi_paf_config"
224235
fi
@@ -275,6 +286,7 @@ gn_args=(
275286
"chip_project_config_include_dirs=[\"//config/python\"]"
276287
"chip_config_network_layer_ble=$enable_ble"
277288
"chip_enable_ble=$enable_ble"
289+
"chip_enable_nfc_based_commissioning=$enable_nfc"
278290
"chip_inet_config_enable_ipv4=$enable_ipv4"
279291
"chip_crypto=\"$chip_crypto\""
280292
"chip_build_controller_dynamic_server=$chip_build_controller_dynamic_server"

src/controller/python/ChipDeviceController-ScriptBinding.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ PyChipError pychip_DeviceController_GetNodeId(chip::Controller::DeviceCommission
145145
// Rendezvous
146146
PyChipError pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
147147
bool isShortDiscriminator, uint32_t setupPINCode, chip::NodeId nodeid);
148+
PyChipError pychip_DeviceController_ConnectNFC(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
149+
uint32_t setupPINCode, chip::NodeId nodeid);
148150
PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
149151
uint32_t setupPINCode, chip::NodeId nodeid);
150152
PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload,
@@ -436,6 +438,22 @@ PyChipError pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissio
436438
sCommissioningParameters));
437439
}
438440

441+
PyChipError pychip_DeviceController_ConnectNFC(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
442+
uint32_t setupPINCode, chip::NodeId nodeid)
443+
{
444+
SetupDiscriminator setupDiscriminator;
445+
446+
// With NFC, only a long discriminator can be used
447+
setupDiscriminator.SetLongValue(discriminator);
448+
449+
return ToPyChipError(devCtrl->PairDevice(nodeid,
450+
chip::RendezvousParameters()
451+
.SetPeerAddress(Transport::PeerAddress::NFC(discriminator))
452+
.SetSetupPINCode(setupPINCode)
453+
.SetSetupDiscriminator(setupDiscriminator),
454+
sCommissioningParameters));
455+
}
456+
439457
PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
440458
uint32_t setupPINCode, chip::NodeId nodeid)
441459
{

src/controller/python/matter/ChipDeviceCtrl.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,6 @@ async def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, i
719719
nodeid (int): Node id of the device.
720720
isShortDiscriminator (Optional[bool]): Optional short discriminator.
721721
722-
723722
Returns:
724723
int: Effective Node ID of the device (as defined by the assigned NOC).
725724
'''
@@ -734,6 +733,29 @@ async def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, i
734733

735734
return await asyncio.futures.wrap_future(ctx.future)
736735

736+
async def ConnectNFC(self, discriminator: int, setupPinCode: int, nodeid: int) -> int:
737+
'''
738+
Connect to a NFC device via PASE using the given discriminator and setup pin code.
739+
740+
Args:
741+
discriminator (int): The long discriminator for the DNS-SD advertisement. Valid range: 0-4095.
742+
setupPinCode (int): The setup pin code of the device.
743+
nodeid (int): Node id of the device.
744+
745+
Returns:
746+
int: Effective Node ID of the device (as defined by the assigned NOC).
747+
'''
748+
self.CheckIsActive()
749+
750+
async with self._commissioning_context as ctx:
751+
self._enablePairingCompleteCallback(True)
752+
await self._ChipStack.CallAsync(
753+
lambda: self._dmLib.pychip_DeviceController_ConnectNFC(
754+
self.devCtrl, discriminator, setupPinCode, nodeid)
755+
)
756+
757+
return await asyncio.futures.wrap_future(ctx.future)
758+
737759
async def UnpairDevice(self, nodeid: int) -> None:
738760
'''
739761
Unpairs the device with the specified node ID.
@@ -2317,6 +2339,10 @@ def _InitLib(self):
23172339
c_void_p, c_uint16, c_bool, c_uint32, c_uint64]
23182340
self._dmLib.pychip_DeviceController_ConnectBLE.restype = PyChipError
23192341

2342+
self._dmLib.pychip_DeviceController_ConnectNFC.argtypes = [
2343+
c_void_p, c_uint16, c_uint32, c_uint64]
2344+
self._dmLib.pychip_DeviceController_ConnectNFC.restype = PyChipError
2345+
23202346
self._dmLib.pychip_DeviceController_SetThreadOperationalDataset.argtypes = [
23212347
c_char_p, c_uint32]
23222348
self._dmLib.pychip_DeviceController_SetThreadOperationalDataset.restype = PyChipError
@@ -2658,7 +2684,7 @@ async def Commission(self, nodeid) -> int:
26582684

26592685
return await asyncio.futures.wrap_future(ctx.future)
26602686

2661-
async def CommissionThread(self, discriminator, setupPinCode, nodeId, threadOperationalDataset: bytes, isShortDiscriminator: bool = False) -> int:
2687+
async def CommissionBleThread(self, discriminator, setupPinCode, nodeId, threadOperationalDataset: bytes, isShortDiscriminator: bool = False) -> int:
26622688
'''
26632689
Commissions a Thread device over BLE.
26642690
@@ -2675,7 +2701,23 @@ async def CommissionThread(self, discriminator, setupPinCode, nodeId, threadOper
26752701
self.SetThreadOperationalDataset(threadOperationalDataset)
26762702
return await self.ConnectBLE(discriminator, setupPinCode, nodeId, isShortDiscriminator)
26772703

2678-
async def CommissionWiFi(self, discriminator, setupPinCode, nodeId, ssid: str, credentials: str, isShortDiscriminator: bool = False) -> int:
2704+
async def CommissionNfcThread(self, discriminator, setupPinCode, nodeId, threadOperationalDataset: bytes) -> int:
2705+
'''
2706+
Commissions a Thread device over NFC.
2707+
2708+
Args:
2709+
discriminator (int): The long discriminator for the DNS-SD advertisement. Valid range: 0-4095.
2710+
setupPinCode (int): The setup pin code of the device.
2711+
nodeId (int): Node id of the device.
2712+
threadOperationalDataset (bytes): The Thread operational dataset for commissioning.
2713+
2714+
Returns:
2715+
int: Effective Node ID of the device (as defined by the assigned NOC).
2716+
'''
2717+
self.SetThreadOperationalDataset(threadOperationalDataset)
2718+
return await self.ConnectNFC(discriminator, setupPinCode, nodeId)
2719+
2720+
async def CommissionBleWiFi(self, discriminator, setupPinCode, nodeId, ssid: str, credentials: str, isShortDiscriminator: bool = False) -> int:
26792721
'''
26802722
Commissions a Wi-Fi device over BLE.
26812723

src/controller/python/matter/setup_payload/setup_payload.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,7 @@ def supports_ble_commissioning(self) -> bool:
180180
@property
181181
def supports_on_network_commissioning(self) -> bool:
182182
return (self.rendezvous_information & 0b100) != 0
183+
184+
@property
185+
def supports_nfc_commissioning(self) -> bool:
186+
return (self.rendezvous_information & 0b10000) != 0

src/python_testing/matter_testing_infrastructure/matter/testing/commissioning.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ async def commission_device(
144144

145145
if commissioning_info.tc_version_to_simulate is not None and commissioning_info.tc_user_response_to_simulate is not None:
146146
LOGGER.debug(
147-
f"Setting TC Acknowledgements to version {commissioning_info.tc_version_to_simulate} with user response {commissioning_info.tc_user_response_to_simulate}."
147+
f"Setting TC Acknowledgements to version {commissioning_info.tc_version_to_simulate} with user response {
148+
commissioning_info.tc_user_response_to_simulate}."
148149
)
149150
dev_ctrl.SetTCAcknowledgements(commissioning_info.tc_version_to_simulate, commissioning_info.tc_user_response_to_simulate)
150151

@@ -165,7 +166,7 @@ async def commission_device(
165166
# Type assertions to help mypy understand these are not None after the asserts
166167
assert commissioning_info.wifi_ssid is not None
167168
assert commissioning_info.wifi_passphrase is not None
168-
await dev_ctrl.CommissionWiFi(
169+
await dev_ctrl.CommissionBleWiFi(
169170
info.filter_value,
170171
info.passcode,
171172
node_id,
@@ -183,7 +184,7 @@ async def commission_device(
183184
"Thread dataset must be provided for ble-thread commissioning")
184185
# Type assertion to help mypy understand this is not None after the assert
185186
assert commissioning_info.thread_operational_dataset is not None
186-
await dev_ctrl.CommissionThread(
187+
await dev_ctrl.CommissionBleThread(
187188
info.filter_value,
188189
info.passcode,
189190
node_id,
@@ -194,6 +195,22 @@ async def commission_device(
194195
except ChipStackError as e: # chipstack-ok: Can not use 'with' because we handle and return the exception, not assert it
195196
LOGGER.error("Commissioning failed: %s" % e)
196197
return PairingStatus(exception=e)
198+
elif commissioning_info.commissioning_method == "nfc-thread":
199+
try:
200+
asserts.assert_is_not_none(commissioning_info.thread_operational_dataset,
201+
"Thread dataset must be provided for nfc-thread commissioning")
202+
# Type assertion to help mypy understand this is not None after the assert
203+
assert commissioning_info.thread_operational_dataset is not None
204+
await dev_ctrl.CommissionNfcThread(
205+
info.filter_value,
206+
info.passcode,
207+
node_id,
208+
commissioning_info.thread_operational_dataset,
209+
)
210+
return PairingStatus()
211+
except ChipStackError as e: # chipstack-ok: Can not use 'with' because we handle and return the exception, not assert it
212+
LOGGER.error("Commissioning failed: %s" % e)
213+
return PairingStatus(exception=e)
197214
else:
198215
raise ValueError("Invalid commissioning method %s!" % commissioning_info.commissioning_method)
199216

src/python_testing/matter_testing_infrastructure/matter/testing/runner.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -697,9 +697,9 @@ def populate_commissioning_args(args: argparse.Namespace, config) -> bool:
697697

698698
config.wifi_ssid = args.wifi_ssid
699699
config.wifi_passphrase = args.wifi_passphrase
700-
elif config.commissioning_method == "ble-thread":
700+
elif config.commissioning_method in ["ble-thread", "nfc-thread"]:
701701
if args.thread_dataset_hex is None:
702-
print("error: missing --thread-dataset-hex <DATASET_HEX> for --commissioning-method ble-thread!")
702+
print("error: missing --thread-dataset-hex <DATASET_HEX> for --commissioning-method ble-thread or nfc-thread!")
703703
return False
704704
config.thread_operational_dataset = args.thread_dataset_hex
705705
elif config.commissioning_method == "on-network-ip":
@@ -820,11 +820,11 @@ def parse_matter_test_args(argv: Optional[List[str]] = None):
820820

821821
commission_group.add_argument('-m', '--commissioning-method', type=str,
822822
metavar='METHOD_NAME',
823-
choices=["on-network", "ble-wifi", "ble-thread"],
823+
choices=["on-network", "ble-wifi", "ble-thread", "nfc-thread"],
824824
help='Name of commissioning method to use')
825825
commission_group.add_argument('--in-test-commissioning-method', type=str,
826826
metavar='METHOD_NAME',
827-
choices=["on-network", "ble-wifi", "ble-thread"],
827+
choices=["on-network", "ble-wifi", "ble-thread", "nfc-thread"],
828828
help='Name of commissioning method to use, for commissioning tests')
829829
commission_group.add_argument('-d', '--discriminator', type=int_decimal_or_hex,
830830
metavar='LONG_DISCRIMINATOR',

0 commit comments

Comments
 (0)