blob: 65c8e086fae3853f4eddacfe542722eae5fbd1e5 [file] [log] [blame]
yunhanw-google90ea3142020-10-01 13:53:26 -07001/*
2 *
Evgeny Margolisc69b6f12022-02-07 09:34:01 -08003 * Copyright (c) 2020-2022 Project CHIP Authors
yunhanw-google90ea3142020-10-01 13:53:26 -07004 * Copyright (c) 2019-2020 Google LLC.
5 * Copyright (c) 2013-2018 Nest Labs, Inc.
6 * All rights reserved.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21/**
22 * @file
23 * Implementation of the native methods expected by the Python
24 * version of Chip Device Manager.
25 *
26 */
27
28#include <errno.h>
29#include <fcntl.h>
Damian Królika5784162021-03-05 16:56:42 +010030#include <memory>
yunhanw-google90ea3142020-10-01 13:53:26 -070031#include <stdio.h>
32#include <stdlib.h>
33#include <sys/time.h>
Kevin Schoedel57874d42021-07-20 21:10:00 -040034#include <type_traits>
yunhanw-google90ea3142020-10-01 13:53:26 -070035#include <unistd.h>
36
37#include <system/SystemError.h>
38#include <system/SystemLayer.h>
39
40#include <inttypes.h>
41#include <net/if.h>
42
Pankaj Garga04576d2021-11-08 15:04:13 -080043#include <app/DeviceProxy.h>
Song Guoa77a6622021-01-29 13:13:02 +080044#include <app/InteractionModelEngine.h>
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +020045#include <app/server/Dnssd.h>
C Freeman8ffe4222022-02-02 14:21:16 -050046#include <controller/AutoCommissioner.h>
Song Guoe2590b82021-02-11 03:30:13 +080047#include <controller/CHIPDeviceController.h>
Sagar Dhawanae69dd72021-09-29 15:13:09 -070048#include <controller/CHIPDeviceControllerFactory.h>
C Freeman8bedafa2021-12-15 09:27:51 -050049#include <controller/CommissioningDelegate.h>
Boris Zbarsky710b9d82022-03-24 16:08:47 -040050#include <controller/CommissioningWindowOpener.h>
Hamid Abubakr94ccbdd2023-04-14 03:20:35 +040051#include <controller/CurrentFabricRemover.h>
Pankaj Garg0238a6c2021-05-10 07:33:19 -070052#include <controller/ExampleOperationalCredentialsIssuer.h>
Jerry Johnsa7a70ae2022-07-07 14:48:18 -070053
54#include <controller/python/ChipDeviceController-ScriptDevicePairingDelegate.h>
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -040055#include <controller/python/ChipDeviceController-ScriptPairingDeviceDiscoveryDelegate.h>
Jerry Johnsa7a70ae2022-07-07 14:48:18 -070056#include <controller/python/ChipDeviceController-StorageDelegate.h>
57#include <controller/python/chip/interaction_model/Delegate.h>
Song GUOb9d32ec2022-10-24 14:40:11 +080058#include <controller/python/chip/native/PyChipError.h>
Jerry Johnsa7a70ae2022-07-07 14:48:18 -070059
Tennessee Carmel-Veilleux1c03d9c2022-03-30 17:44:08 -040060#include <credentials/GroupDataProviderImpl.h>
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -040061#include <credentials/PersistentStorageOpCertStore.h>
Tennessee Carmel-Veilleux22fb6c32022-02-22 16:49:16 -050062#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
63#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
Damian Królikb07872c2023-02-17 13:56:47 +010064#include <crypto/RawKeySessionKeystore.h>
cecille81850192021-05-11 21:43:14 -040065#include <inet/IPAddress.h>
Martin Turon82bfcd52023-01-09 13:30:38 -080066#include <lib/core/TLV.h>
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +020067#include <lib/dnssd/Resolver.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080068#include <lib/support/BytesToHex.h>
69#include <lib/support/CHIPMem.h>
70#include <lib/support/CodeUtils.h>
71#include <lib/support/DLLUtil.h>
72#include <lib/support/ScopedBuffer.h>
73#include <lib/support/logging/CHIPLogging.h>
Song GUOed3b2332021-07-21 02:12:40 +080074#include <platform/CHIPDeviceLayer.h>
cecille81850192021-05-11 21:43:14 -040075#include <setup_payload/QRCodeSetupPayloadParser.h>
Boris Zbarsky710b9d82022-03-24 16:08:47 -040076#include <system/SystemClock.h>
yunhanw-google90ea3142020-10-01 13:53:26 -070077
Jerry Johnsa7a70ae2022-07-07 14:48:18 -070078#include <platform/CommissionableDataProvider.h>
79#include <platform/PlatformManager.h>
80#include <platform/TestOnlyCommissionableDataProvider.h>
81
Song Guo830d1f82020-12-10 01:59:07 +080082using namespace chip;
yunhanw-google90ea3142020-10-01 13:53:26 -070083using namespace chip::Ble;
Song Guoe2590b82021-02-11 03:30:13 +080084using namespace chip::Controller;
Marty Leisner0e529702021-09-27 10:55:08 -040085using namespace chip::Credentials;
Song GUOed3b2332021-07-21 02:12:40 +080086using namespace chip::DeviceLayer;
yunhanw-google90ea3142020-10-01 13:53:26 -070087
88extern "C" {
yunhanw-google90ea3142020-10-01 13:53:26 -070089typedef void (*ConstructBytesArrayFunct)(const uint8_t * dataBuf, uint32_t dataLen);
90typedef void (*LogMessageFunct)(uint64_t time, uint64_t timeUS, const char * moduleName, uint8_t category, const char * msg);
Song GUOb9d32ec2022-10-24 14:40:11 +080091typedef void (*DeviceAvailableFunc)(DeviceProxy * device, PyChipError err);
Song GUOed3b2332021-07-21 02:12:40 +080092typedef void (*ChipThreadTaskRunnerFunct)(intptr_t context);
Hamid Abubakr94ccbdd2023-04-14 03:20:35 +040093typedef void (*DeviceUnpairingCompleteFunct)(uint64_t nodeId, PyChipError error);
yunhanw-google90ea3142020-10-01 13:53:26 -070094}
95
Song Guoe2590b82021-02-11 03:30:13 +080096namespace {
C Freeman8bedafa2021-12-15 09:27:51 -050097chip::Platform::ScopedMemoryBuffer<uint8_t> sSsidBuf;
98chip::Platform::ScopedMemoryBuffer<uint8_t> sCredsBuf;
99chip::Platform::ScopedMemoryBuffer<uint8_t> sThreadBuf;
C Freemanac3535b2023-07-18 13:32:59 -0400100chip::Platform::ScopedMemoryBuffer<char> sDefaultNTPBuf;
101app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type sDSTBuf;
102app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type sTimeZoneBuf;
C Freeman8bedafa2021-12-15 09:27:51 -0500103chip::Controller::CommissioningParameters sCommissioningParameters;
C Freeman8ffe4222022-02-02 14:21:16 -0500104
Song Guoe2590b82021-02-11 03:30:13 +0800105} // namespace
yunhanw-google90ea3142020-10-01 13:53:26 -0700106
Jerry Johnsf68cd642022-01-28 16:39:08 -0800107chip::Controller::ScriptDevicePairingDelegate sPairingDelegate;
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -0400108chip::Controller::ScriptPairingDeviceDiscoveryDelegate sPairingDeviceDiscoveryDelegate;
Tennessee Carmel-Veilleux1c03d9c2022-03-30 17:44:08 -0400109chip::Credentials::GroupDataProviderImpl sGroupDataProvider;
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400110chip::Credentials::PersistentStorageOpCertStore sPersistentStorageOpCertStore;
Damian Królikb07872c2023-02-17 13:56:47 +0100111chip::Crypto::RawKeySessionKeystore sSessionKeystore;
Jerry Johnsf68cd642022-01-28 16:39:08 -0800112
yunhanw-google90ea3142020-10-01 13:53:26 -0700113// NOTE: Remote device ID is in sync with the echo server device id
114// At some point, we may want to add an option to connect to a device without
115// knowing its id, because the ID can be learned on the first response that is received.
Kevin Schoedel5f19e992021-03-02 14:36:20 -0500116chip::NodeId kDefaultLocalDeviceId = chip::kTestControllerNodeId;
117chip::NodeId kRemoteDeviceId = chip::kTestDeviceNodeId;
yunhanw-google90ea3142020-10-01 13:53:26 -0700118
yunhanw-google90ea3142020-10-01 13:53:26 -0700119extern "C" {
Song GUOb9d32ec2022-10-24 14:40:11 +0800120PyChipError pychip_DeviceController_StackInit(Controller::Python::StorageAdapter * storageAdapter, bool enableServerInteractions);
121PyChipError pychip_DeviceController_StackShutdown();
Jerry Johnsf68cd642022-01-28 16:39:08 -0800122
Song GUOb9d32ec2022-10-24 14:40:11 +0800123PyChipError pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl,
124 chip::NodeId localDeviceId, bool useTestCommissioner);
125PyChipError pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl);
126PyChipError pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
127 char * outAddress, uint64_t maxAddressLen, uint16_t * outPort);
128PyChipError pychip_DeviceController_GetCompressedFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId);
129PyChipError pychip_DeviceController_GetFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId);
130PyChipError pychip_DeviceController_GetNodeId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outNodeId);
yunhanw-google90ea3142020-10-01 13:53:26 -0700131
Song Guofe1eeb42020-10-30 04:17:04 +0800132// Rendezvous
Song GUOb9d32ec2022-10-24 14:40:11 +0800133PyChipError pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
134 uint32_t setupPINCode, chip::NodeId nodeid);
135PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
136 uint32_t setupPINCode, chip::NodeId nodeid);
137PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload,
138 chip::NodeId nodeid);
Hamid Abubakr94ccbdd2023-04-14 03:20:35 +0400139PyChipError pychip_DeviceController_UnpairDevice(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId remoteDeviceId,
140 DeviceUnpairingCompleteFunct callback);
Song GUOb9d32ec2022-10-24 14:40:11 +0800141PyChipError pychip_DeviceController_SetThreadOperationalDataset(const char * threadOperationalDataset, uint32_t size);
142PyChipError pychip_DeviceController_SetWiFiCredentials(const char * ssid, const char * credentials);
C Freemanac3535b2023-07-18 13:32:59 -0400143PyChipError pychip_DeviceController_SetTimeZone(int32_t offset, uint64_t validAt);
144PyChipError pychip_DeviceController_SetDSTOffset(int32_t offset, uint64_t validStarting, uint64_t validUntil);
145PyChipError pychip_DeviceController_SetDefaultNtp(const char * defaultNTP);
146PyChipError pychip_DeviceController_SetTrustedTimeSource(chip::NodeId nodeId, chip::EndpointId endpoint);
147PyChipError pychip_DeviceController_ResetCommissioningParameters();
Song GUOb9d32ec2022-10-24 14:40:11 +0800148PyChipError pychip_DeviceController_CloseSession(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid);
149PyChipError pychip_DeviceController_EstablishPASESessionIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
C Freeman5d2beb72023-07-12 18:23:50 -0400150 uint32_t setupPINCode, chip::NodeId nodeid, uint16_t port);
Jerry Johns71da6502022-12-11 19:32:16 -0800151PyChipError pychip_DeviceController_EstablishPASESessionBLE(chip::Controller::DeviceCommissioner * devCtrl, uint32_t setupPINCode,
152 uint16_t discriminator, chip::NodeId nodeid);
Song GUOb9d32ec2022-10-24 14:40:11 +0800153PyChipError pychip_DeviceController_Commission(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid);
Song Guofe1eeb42020-10-30 04:17:04 +0800154
Song GUOb9d32ec2022-10-24 14:40:11 +0800155PyChipError pychip_DeviceController_DiscoverCommissionableNodesLongDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
156 uint16_t long_discriminator);
157PyChipError pychip_DeviceController_DiscoverAllCommissionableNodes(chip::Controller::DeviceCommissioner * devCtrl);
C Freeman8a535282021-06-22 22:54:19 -0400158
Song GUOb9d32ec2022-10-24 14:40:11 +0800159PyChipError pychip_DeviceController_DiscoverCommissionableNodesShortDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
160 uint16_t short_discriminator);
161PyChipError pychip_DeviceController_DiscoverCommissionableNodesVendor(chip::Controller::DeviceCommissioner * devCtrl,
162 uint16_t vendor);
163PyChipError pychip_DeviceController_DiscoverCommissionableNodesDeviceType(chip::Controller::DeviceCommissioner * devCtrl,
164 uint16_t device_type);
165PyChipError pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl);
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -0400166
Song GUOb9d32ec2022-10-24 14:40:11 +0800167PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, uint64_t nodeId,
tianfeng-yang8cb1cb72023-07-19 10:16:33 +0800168 uint32_t setupPasscode, const uint8_t filterType, const char * filterParam,
169 uint32_t discoveryTimeoutMsec);
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -0400170
Song GUOb9d32ec2022-10-24 14:40:11 +0800171PyChipError pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext);
Song GUOed3b2332021-07-21 02:12:40 +0800172
Song GUOb9d32ec2022-10-24 14:40:11 +0800173PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid,
174 uint16_t timeout, uint32_t iteration, uint16_t discriminator,
175 uint8_t optionInt);
Yufeng Wang275368c2021-08-31 17:42:23 -0700176
cecille81850192021-05-11 21:43:14 -0400177void pychip_DeviceController_PrintDiscoveredDevices(chip::Controller::DeviceCommissioner * devCtrl);
178bool pychip_DeviceController_GetIPForDiscoveredDevice(chip::Controller::DeviceCommissioner * devCtrl, int idx, char * addrStr,
179 uint32_t len);
180
Song Guoe2590b82021-02-11 03:30:13 +0800181// Pairing Delegate
Song GUOb9d32ec2022-10-24 14:40:11 +0800182PyChipError
Song Guoe2590b82021-02-11 03:30:13 +0800183pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl,
184 chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback);
Song Guofe1eeb42020-10-30 04:17:04 +0800185
Song GUOb9d32ec2022-10-24 14:40:11 +0800186PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback(
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400187 chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback);
188
Song GUOb9d32ec2022-10-24 14:40:11 +0800189PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback(
C Freemanc3b18102022-04-04 16:17:09 -0400190 chip::Controller::DeviceCommissioner * devCtrl,
191 chip::Controller::DevicePairingDelegate_OnCommissioningStatusUpdateFunct callback);
C Freeman89d538c2023-01-26 12:29:48 -0500192PyChipError pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback(
193 chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback);
C Freemanc3b18102022-04-04 16:17:09 -0400194
Song Guo87142e02021-04-21 09:00:00 +0800195// BLE
Song GUOb9d32ec2022-10-24 14:40:11 +0800196PyChipError pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::DeviceCommissioner * devCtrl);
Song Guo87142e02021-04-21 09:00:00 +0800197
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500198uint8_t pychip_DeviceController_GetLogFilter();
199void pychip_DeviceController_SetLogFilter(uint8_t category);
yunhanw-google90ea3142020-10-01 13:53:26 -0700200
Kevin Schoedel57874d42021-07-20 21:10:00 -0400201const char * pychip_Stack_ErrorToString(ChipError::StorageType err);
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500202const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t statusCode);
203void pychip_Stack_SetLogFunct(LogMessageFunct logFunct);
Song Guoa77a6622021-01-29 13:13:02 +0800204
Song GUOb9d32ec2022-10-24 14:40:11 +0800205PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
206 DeviceAvailableFunc callback);
207PyChipError pychip_FreeOperationalDeviceProxy(chip::OperationalDeviceProxy * deviceProxy);
208PyChipError pychip_GetLocalSessionId(chip::OperationalDeviceProxy * deviceProxy, uint16_t * localSessionId);
209PyChipError pychip_GetNumSessionsToPeer(chip::OperationalDeviceProxy * deviceProxy, uint32_t * numSessions);
C Freeman83ecf9c2023-06-02 18:32:53 -0400210PyChipError pychip_GetAttestationChallenge(chip::OperationalDeviceProxy * deviceProxy, uint8_t * buf, size_t * size);
Song GUOb9d32ec2022-10-24 14:40:11 +0800211PyChipError pychip_GetDeviceBeingCommissioned(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
212 CommissioneeDeviceProxy ** proxy);
213PyChipError pychip_ExpireSessions(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId);
Tennessee Carmel-Veilleuxc3cd0042022-07-08 13:49:30 -0400214
Pankaj Garga04576d2021-11-08 15:04:13 -0800215uint64_t pychip_GetCommandSenderHandle(chip::DeviceProxy * device);
Song GUO75f38952021-10-13 04:13:10 +0800216
Song GUOb9d32ec2022-10-24 14:40:11 +0800217PyChipError pychip_InteractionModel_ShutdownSubscription(SubscriptionId subscriptionId);
Jerry Johnsf68cd642022-01-28 16:39:08 -0800218
219//
220// Storage
221//
Jerry Johnsc517ba22022-08-18 09:48:09 -0700222void * pychip_Storage_InitializeStorageAdapter(chip::Controller::Python::PyObject * context,
223 chip::Controller::Python::SyncSetKeyValueCb setCb,
224 chip::Controller::Python::SetGetKeyValueCb getCb,
225 chip::Controller::Python::SyncDeleteKeyValueCb deleteCb);
226void pychip_Storage_ShutdownAdapter(chip::Controller::Python::StorageAdapter * storageAdapter);
yunhanw-google90ea3142020-10-01 13:53:26 -0700227}
228
Jerry Johnsc517ba22022-08-18 09:48:09 -0700229void * pychip_Storage_InitializeStorageAdapter(chip::Controller::Python::PyObject * context,
230 chip::Controller::Python::SyncSetKeyValueCb setCb,
231 chip::Controller::Python::SetGetKeyValueCb getCb,
232 chip::Controller::Python::SyncDeleteKeyValueCb deleteCb)
yunhanw-google90ea3142020-10-01 13:53:26 -0700233{
Jerry Johnsc517ba22022-08-18 09:48:09 -0700234 auto ptr = new chip::Controller::Python::StorageAdapter(context, setCb, getCb, deleteCb);
235 return ptr;
Jerry Johnsf68cd642022-01-28 16:39:08 -0800236}
yunhanw-google90ea3142020-10-01 13:53:26 -0700237
Jerry Johnsc517ba22022-08-18 09:48:09 -0700238void pychip_Storage_ShutdownAdapter(chip::Controller::Python::StorageAdapter * storageAdapter)
Jerry Johnsf68cd642022-01-28 16:39:08 -0800239{
Jerry Johnsc517ba22022-08-18 09:48:09 -0700240 delete storageAdapter;
Jerry Johnsf68cd642022-01-28 16:39:08 -0800241}
Song Guo9ab3c902021-04-09 06:08:35 +0800242
Song GUOb9d32ec2022-10-24 14:40:11 +0800243PyChipError pychip_DeviceController_StackInit(Controller::Python::StorageAdapter * storageAdapter, bool enableServerInteractions)
Jerry Johnsf68cd642022-01-28 16:39:08 -0800244{
Jerry Johnsc517ba22022-08-18 09:48:09 -0700245 VerifyOrDie(storageAdapter != nullptr);
Sagar Dhawanf0bbca72021-10-27 17:23:34 -0500246
Sagar Dhawanae69dd72021-09-29 15:13:09 -0700247 FactoryInitParams factoryParams;
Tennessee Carmel-Veilleux1c03d9c2022-03-30 17:44:08 -0400248
Jerry Johnsc517ba22022-08-18 09:48:09 -0700249 factoryParams.fabricIndependentStorage = storageAdapter;
Damian Królikb07872c2023-02-17 13:56:47 +0100250 factoryParams.sessionKeystore = &sSessionKeystore;
Jerry Johnsc517ba22022-08-18 09:48:09 -0700251
252 sGroupDataProvider.SetStorageDelegate(storageAdapter);
Damian Królikb07872c2023-02-17 13:56:47 +0100253 sGroupDataProvider.SetSessionKeystore(factoryParams.sessionKeystore);
Song GUOb9d32ec2022-10-24 14:40:11 +0800254 PyReturnErrorOnFailure(ToPyChipError(sGroupDataProvider.Init()));
Terence Hampsonec2b5e32023-02-22 13:22:02 -0500255 Credentials::SetGroupDataProvider(&sGroupDataProvider);
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400256 factoryParams.groupDataProvider = &sGroupDataProvider;
Tennessee Carmel-Veilleux1c03d9c2022-03-30 17:44:08 -0400257
Song GUOb9d32ec2022-10-24 14:40:11 +0800258 PyReturnErrorOnFailure(ToPyChipError(sPersistentStorageOpCertStore.Init(storageAdapter)));
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400259 factoryParams.opCertStore = &sPersistentStorageOpCertStore;
260
Song GUO59fbe3a2022-09-08 00:28:36 +0800261 factoryParams.enableServerInteractions = enableServerInteractions;
Song Guo9ab3c902021-04-09 06:08:35 +0800262
Jerry Johnsa7a70ae2022-07-07 14:48:18 -0700263 // Hack needed due to the fact that DnsSd server uses the CommissionableDataProvider even
264 // when never starting commissionable advertising. This will not be used but prevents
265 // null pointer dereferences.
266 static chip::DeviceLayer::TestOnlyCommissionableDataProvider TestOnlyCommissionableDataProvider;
267 chip::DeviceLayer::SetCommissionableDataProvider(&TestOnlyCommissionableDataProvider);
268
Song GUOb9d32ec2022-10-24 14:40:11 +0800269 PyReturnErrorOnFailure(ToPyChipError(DeviceControllerFactory::GetInstance().Init(factoryParams)));
Jerry Johnsf68cd642022-01-28 16:39:08 -0800270
271 //
272 // In situations where all the controller instances get shutdown, the entire stack is then also
273 // implicitly shutdown. In the REPL, users can create such a situation by manually shutting down
274 // controllers (for example, when they call ChipReplStartup::LoadFabricAdmins multiple times). In
275 // that situation, momentarily, the stack gets de-initialized. This results in further interactions with
276 // the stack being dangerous (and in fact, causes crashes).
277 //
278 // This retain call ensures the stack doesn't get de-initialized in the REPL.
279 //
280 DeviceControllerFactory::GetInstance().RetainSystemState();
281
Jerry Johnsa7a70ae2022-07-07 14:48:18 -0700282 //
283 // Finally, start up the main Matter thread. Any further interactions with the stack
284 // will now need to happen on the Matter thread, OR protected with the stack lock.
285 //
Song GUOb9d32ec2022-10-24 14:40:11 +0800286 PyReturnErrorOnFailure(ToPyChipError(chip::DeviceLayer::PlatformMgr().StartEventLoopTask()));
Jerry Johnsa7a70ae2022-07-07 14:48:18 -0700287
Song GUOb9d32ec2022-10-24 14:40:11 +0800288 return ToPyChipError(CHIP_NO_ERROR);
Jerry Johnsa7a70ae2022-07-07 14:48:18 -0700289}
290
Song GUOb9d32ec2022-10-24 14:40:11 +0800291PyChipError pychip_DeviceController_StackShutdown()
Jerry Johnsa7a70ae2022-07-07 14:48:18 -0700292{
293 ChipLogError(Controller, "Shutting down the stack...");
294
295 //
296 // Let's stop the Matter thread, and wait till the event loop has stopped.
297 //
Song GUOb9d32ec2022-10-24 14:40:11 +0800298 PyReturnErrorOnFailure(ToPyChipError(chip::DeviceLayer::PlatformMgr().StopEventLoopTask()));
Jerry Johnsa7a70ae2022-07-07 14:48:18 -0700299
300 //
301 // There is the symmetric call to match the Retain called at stack initialization
302 // time. This will release all resources (if there are no other controllers active).
303 //
304 DeviceControllerFactory::GetInstance().ReleaseSystemState();
305
306 DeviceControllerFactory::GetInstance().Shutdown();
307
Song GUOb9d32ec2022-10-24 14:40:11 +0800308 return ToPyChipError(CHIP_NO_ERROR);
yunhanw-google90ea3142020-10-01 13:53:26 -0700309}
310
Song GUOb9d32ec2022-10-24 14:40:11 +0800311PyChipError pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
312 char * outAddress, uint64_t maxAddressLen, uint16_t * outPort)
Damian Królika5784162021-03-05 16:56:42 +0100313{
Damian Królika5784162021-03-05 16:56:42 +0100314 Inet::IPAddress address;
Song GUOb9d32ec2022-10-24 14:40:11 +0800315 PyReturnErrorOnFailure(ToPyChipError(devCtrl->GetPeerAddressAndPort(nodeId, address, *outPort)));
Jerry Johnsd94cbdc2022-07-26 08:07:06 -0700316 VerifyOrReturnError(address.ToString(outAddress, static_cast<uint32_t>(maxAddressLen)),
Song GUOb9d32ec2022-10-24 14:40:11 +0800317 ToPyChipError(CHIP_ERROR_BUFFER_TOO_SMALL));
Damian Królika5784162021-03-05 16:56:42 +0100318
Song GUOb9d32ec2022-10-24 14:40:11 +0800319 return ToPyChipError(CHIP_NO_ERROR);
yunhanw-google90ea3142020-10-01 13:53:26 -0700320}
321
Song GUOb9d32ec2022-10-24 14:40:11 +0800322PyChipError pychip_DeviceController_GetCompressedFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId)
Pankaj Garg6efec202021-08-25 10:47:29 -0700323{
324 *outFabricId = devCtrl->GetCompressedFabricId();
Song GUOb9d32ec2022-10-24 14:40:11 +0800325 return ToPyChipError(CHIP_NO_ERROR);
Pankaj Garg6efec202021-08-25 10:47:29 -0700326}
327
Song GUOb9d32ec2022-10-24 14:40:11 +0800328PyChipError pychip_DeviceController_GetFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId)
Yufeng Wangb728b742021-06-16 08:04:17 -0700329{
Pankaj Garg6efec202021-08-25 10:47:29 -0700330 *outFabricId = devCtrl->GetFabricId();
Song GUOb9d32ec2022-10-24 14:40:11 +0800331 return ToPyChipError(CHIP_NO_ERROR);
Yufeng Wangb728b742021-06-16 08:04:17 -0700332}
333
Song GUOb9d32ec2022-10-24 14:40:11 +0800334PyChipError pychip_DeviceController_GetNodeId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outNodeId)
tehampsonf3be2ee2022-06-23 13:10:52 -0400335{
336 *outNodeId = devCtrl->GetNodeId();
Song GUOb9d32ec2022-10-24 14:40:11 +0800337 return ToPyChipError(CHIP_NO_ERROR);
tehampsonf3be2ee2022-06-23 13:10:52 -0400338}
339
Kevin Schoedel57874d42021-07-20 21:10:00 -0400340const char * pychip_DeviceController_ErrorToString(ChipError::StorageType err)
yunhanw-google90ea3142020-10-01 13:53:26 -0700341{
Kevin Schoedel57874d42021-07-20 21:10:00 -0400342 return chip::ErrorStr(CHIP_ERROR(err));
yunhanw-google90ea3142020-10-01 13:53:26 -0700343}
344
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500345const char * pychip_DeviceController_StatusReportToString(uint32_t profileId, uint16_t statusCode)
yunhanw-google90ea3142020-10-01 13:53:26 -0700346{
347 // return chip::StatusReportStr(profileId, statusCode);
Andrei Litvin697b1552022-04-06 10:45:26 -1000348 return nullptr;
yunhanw-google90ea3142020-10-01 13:53:26 -0700349}
350
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500351uint8_t pychip_DeviceController_GetLogFilter()
yunhanw-google90ea3142020-10-01 13:53:26 -0700352{
353#if _CHIP_USE_LOGGING
354 return chip::Logging::GetLogFilter();
355#else
356 return chip::Logging::kLogCategory_None;
357#endif
358}
359
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500360void pychip_DeviceController_SetLogFilter(uint8_t category)
yunhanw-google90ea3142020-10-01 13:53:26 -0700361{
362#if _CHIP_USE_LOGGING
363 chip::Logging::SetLogFilter(category);
364#endif
365}
366
Song GUOb9d32ec2022-10-24 14:40:11 +0800367PyChipError pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
368 uint32_t setupPINCode, chip::NodeId nodeid)
Song Guofe1eeb42020-10-30 04:17:04 +0800369{
Terence Hampson11c0cdf2023-02-09 12:40:19 -0500370 sPairingDelegate.SetExpectingPairingComplete(true);
Song GUOb9d32ec2022-10-24 14:40:11 +0800371 return ToPyChipError(devCtrl->PairDevice(nodeid,
372 chip::RendezvousParameters()
373 .SetPeerAddress(Transport::PeerAddress(Transport::Type::kBle))
374 .SetSetupPINCode(setupPINCode)
375 .SetDiscriminator(discriminator),
376 sCommissioningParameters));
Song Guob94c9802021-01-29 13:58:48 +0800377}
378
Song GUOb9d32ec2022-10-24 14:40:11 +0800379PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
380 uint32_t setupPINCode, chip::NodeId nodeid)
Song Guo830d1f82020-12-10 01:59:07 +0800381{
Song Guo830d1f82020-12-10 01:59:07 +0800382 chip::Inet::IPAddress peerAddr;
383 chip::Transport::PeerAddress addr;
384 chip::RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode);
385
Song GUOb9d32ec2022-10-24 14:40:11 +0800386 VerifyOrReturnError(chip::Inet::IPAddress::FromString(peerAddrStr, peerAddr), ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
Jerry Johnsf68cd642022-01-28 16:39:08 -0800387
Song Guo830d1f82020-12-10 01:59:07 +0800388 // TODO: IP rendezvous should use TCP connection.
Andrei Litvine68bd6c2022-02-11 11:29:49 -0500389 addr.SetTransportType(chip::Transport::Type::kUdp).SetIPAddress(peerAddr);
Song Guo830d1f82020-12-10 01:59:07 +0800390 params.SetPeerAddress(addr).SetDiscriminator(0);
Jerry Johnsf68cd642022-01-28 16:39:08 -0800391
Terence Hampson11c0cdf2023-02-09 12:40:19 -0500392 sPairingDelegate.SetExpectingPairingComplete(true);
Song GUOb9d32ec2022-10-24 14:40:11 +0800393 return ToPyChipError(devCtrl->PairDevice(nodeid, params, sCommissioningParameters));
C Freeman8bedafa2021-12-15 09:27:51 -0500394}
395
Song GUOb9d32ec2022-10-24 14:40:11 +0800396PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload,
397 chip::NodeId nodeid)
Song GUOaaad7392022-05-19 23:30:37 +0800398{
Terence Hampson11c0cdf2023-02-09 12:40:19 -0500399 sPairingDelegate.SetExpectingPairingComplete(true);
Song GUOb9d32ec2022-10-24 14:40:11 +0800400 return ToPyChipError(devCtrl->PairDevice(nodeid, onboardingPayload, sCommissioningParameters));
Song GUOaaad7392022-05-19 23:30:37 +0800401}
402
Hamid Abubakr94ccbdd2023-04-14 03:20:35 +0400403namespace {
404struct UnpairDeviceCallback
405{
406 UnpairDeviceCallback(DeviceUnpairingCompleteFunct callback, chip::Controller::CurrentFabricRemover * remover) :
407 mOnCurrentFabricRemove(OnCurrentFabricRemoveFn, this), mCallback(callback), mRemover(remover)
408 {}
409
410 static void OnCurrentFabricRemoveFn(void * context, chip::NodeId nodeId, CHIP_ERROR error)
411 {
412 auto * self = static_cast<UnpairDeviceCallback *>(context);
413 self->mCallback(nodeId, ToPyChipError(error));
414 delete self->mRemover;
415 delete self;
416 }
417
418 Callback::Callback<OnCurrentFabricRemove> mOnCurrentFabricRemove;
419 DeviceUnpairingCompleteFunct mCallback;
420 chip::Controller::CurrentFabricRemover * mRemover;
421};
422} // anonymous namespace
423
424PyChipError pychip_DeviceController_UnpairDevice(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid,
425 DeviceUnpairingCompleteFunct callback)
426{
427 // Create a new CurrentFabricRemover instance
428 auto * fabricRemover = new chip::Controller::CurrentFabricRemover(devCtrl);
429
430 auto * callbacks = new UnpairDeviceCallback(callback, fabricRemover);
431
432 // Pass the callback and nodeid to the RemoveCurrentFabric function
433 CHIP_ERROR err = fabricRemover->RemoveCurrentFabric(nodeid, &callbacks->mOnCurrentFabricRemove);
434 if (err != CHIP_NO_ERROR)
435 {
436 delete fabricRemover;
437 delete callbacks;
438 }
439 // Else will clean up when the callback is called.
440 return ToPyChipError(err);
441}
442
Song GUOb9d32ec2022-10-24 14:40:11 +0800443PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, uint64_t nodeId,
tianfeng-yang8cb1cb72023-07-19 10:16:33 +0800444 uint32_t setupPasscode, const uint8_t filterType, const char * filterParam,
445 uint32_t discoveryTimeoutMsec)
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -0400446{
447 Dnssd::DiscoveryFilter filter(static_cast<Dnssd::DiscoveryFilterType>(filterType));
448 switch (static_cast<Dnssd::DiscoveryFilterType>(filterType))
449 {
450 case chip::Dnssd::DiscoveryFilterType::kNone:
451 break;
452 case chip::Dnssd::DiscoveryFilterType::kShortDiscriminator:
453 case chip::Dnssd::DiscoveryFilterType::kLongDiscriminator:
454 case chip::Dnssd::DiscoveryFilterType::kCompressedFabricId:
455 case chip::Dnssd::DiscoveryFilterType::kVendorId:
456 case chip::Dnssd::DiscoveryFilterType::kDeviceType: {
457 // For any numerical filter, convert the string to a filter value
458 errno = 0;
459 unsigned long long int numericalArg = strtoull(filterParam, nullptr, 0);
460 if ((numericalArg == ULLONG_MAX) && (errno == ERANGE))
461 {
Song GUOb9d32ec2022-10-24 14:40:11 +0800462 return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT);
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -0400463 }
464 filter.code = static_cast<uint64_t>(numericalArg);
465 break;
466 }
467 case chip::Dnssd::DiscoveryFilterType::kCommissioningMode:
468 break;
469 case chip::Dnssd::DiscoveryFilterType::kCommissioner:
470 filter.code = 1;
471 break;
472 case chip::Dnssd::DiscoveryFilterType::kInstanceName:
473 filter.code = 0;
474 filter.instanceName = filterParam;
475 break;
476 default:
Song GUOb9d32ec2022-10-24 14:40:11 +0800477 return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT);
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -0400478 }
479
tianfeng-yang8cb1cb72023-07-19 10:16:33 +0800480 sPairingDelegate.SetExpectingPairingComplete(true);
481 CHIP_ERROR err = sPairingDeviceDiscoveryDelegate.Init(nodeId, setupPasscode, sCommissioningParameters, &sPairingDelegate,
482 devCtrl, discoveryTimeoutMsec);
483 VerifyOrReturnError(err == CHIP_NO_ERROR, ToPyChipError(err));
Song GUOb9d32ec2022-10-24 14:40:11 +0800484 return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
Tennessee Carmel-Veilleux88bc0b22022-08-03 01:17:35 -0400485}
486
Song GUOb9d32ec2022-10-24 14:40:11 +0800487PyChipError pychip_DeviceController_SetThreadOperationalDataset(const char * threadOperationalDataset, uint32_t size)
C Freeman8bedafa2021-12-15 09:27:51 -0500488{
Song GUOb9d32ec2022-10-24 14:40:11 +0800489 ReturnErrorCodeIf(!sThreadBuf.Alloc(size), ToPyChipError(CHIP_ERROR_NO_MEMORY));
C Freeman8bedafa2021-12-15 09:27:51 -0500490 memcpy(sThreadBuf.Get(), threadOperationalDataset, size);
491 sCommissioningParameters.SetThreadOperationalDataset(ByteSpan(sThreadBuf.Get(), size));
Song GUOb9d32ec2022-10-24 14:40:11 +0800492 return ToPyChipError(CHIP_NO_ERROR);
C Freeman8bedafa2021-12-15 09:27:51 -0500493}
Song GUOb9d32ec2022-10-24 14:40:11 +0800494PyChipError pychip_DeviceController_SetWiFiCredentials(const char * ssid, const char * credentials)
C Freeman8bedafa2021-12-15 09:27:51 -0500495{
496 size_t ssidSize = strlen(ssid);
Song GUOb9d32ec2022-10-24 14:40:11 +0800497 ReturnErrorCodeIf(!sSsidBuf.Alloc(ssidSize), ToPyChipError(CHIP_ERROR_NO_MEMORY));
C Freeman8bedafa2021-12-15 09:27:51 -0500498 memcpy(sSsidBuf.Get(), ssid, ssidSize);
499
500 size_t credsSize = strlen(credentials);
Song GUOb9d32ec2022-10-24 14:40:11 +0800501 ReturnErrorCodeIf(!sCredsBuf.Alloc(credsSize), ToPyChipError(CHIP_ERROR_NO_MEMORY));
C Freeman8bedafa2021-12-15 09:27:51 -0500502 memcpy(sCredsBuf.Get(), credentials, credsSize);
503
Vivien Nicolas49721812022-01-06 20:34:14 +0100504 sCommissioningParameters.SetWiFiCredentials(
505 chip::Controller::WiFiCredentials(ByteSpan(sSsidBuf.Get(), ssidSize), ByteSpan(sCredsBuf.Get(), credsSize)));
Song GUOb9d32ec2022-10-24 14:40:11 +0800506 return ToPyChipError(CHIP_NO_ERROR);
Song Guofe1eeb42020-10-30 04:17:04 +0800507}
508
C Freemanac3535b2023-07-18 13:32:59 -0400509PyChipError pychip_DeviceController_SetTimeZone(int32_t offset, uint64_t validAt)
510{
511 sTimeZoneBuf.offset = offset;
512 sTimeZoneBuf.validAt = validAt;
513 app::DataModel::List<app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type> list(&sTimeZoneBuf, 1);
514 sCommissioningParameters.SetTimeZone(list);
515 return ToPyChipError(CHIP_NO_ERROR);
516}
517PyChipError pychip_DeviceController_SetDSTOffset(int32_t offset, uint64_t validStarting, uint64_t validUntil)
518{
519 sDSTBuf.offset = offset;
520 sDSTBuf.validStarting = validStarting;
521 sDSTBuf.validUntil = chip::app::DataModel::MakeNullable(validUntil);
522 app::DataModel::List<app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type> list(&sDSTBuf, 1);
523 sCommissioningParameters.SetDSTOffsets(list);
524 return ToPyChipError(CHIP_NO_ERROR);
525}
526PyChipError pychip_DeviceController_SetDefaultNtp(const char * defaultNTP)
527{
528 size_t len = strlen(defaultNTP);
529 ReturnErrorCodeIf(!sDefaultNTPBuf.Alloc(len), ToPyChipError(CHIP_ERROR_NO_MEMORY));
530 memcpy(sDefaultNTPBuf.Get(), defaultNTP, len);
531 sCommissioningParameters.SetDefaultNTP(chip::app::DataModel::MakeNullable(CharSpan(sDefaultNTPBuf.Get(), len)));
532 return ToPyChipError(CHIP_NO_ERROR);
533}
534
535PyChipError pychip_DeviceController_SetTrustedTimeSource(chip::NodeId nodeId, chip::EndpointId endpoint)
536{
537 chip::app::Clusters::TimeSynchronization::Structs::FabricScopedTrustedTimeSourceStruct::Type timeSource = { .nodeID = nodeId,
538 .endpoint =
539 endpoint };
540 sCommissioningParameters.SetTrustedTimeSource(chip::app::DataModel::MakeNullable(timeSource));
541 return ToPyChipError(CHIP_NO_ERROR);
542}
543
544PyChipError pychip_DeviceController_ResetCommissioningParameters()
545{
546 sCommissioningParameters = CommissioningParameters();
547 return ToPyChipError(CHIP_NO_ERROR);
548}
549
Song GUOb9d32ec2022-10-24 14:40:11 +0800550PyChipError pychip_DeviceController_CloseSession(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid)
Damian Królik88cd7662021-07-17 01:00:54 +0200551{
Jerry Johns0eed15d2022-08-01 17:56:38 -0700552 //
553 // Since we permit multiple controllers per fabric and each is associated with a unique fabric index, closing a session
554 // requires us to do so across all controllers on the same logical fabric.
555 //
Terence Hampson9dbfa912022-08-15 19:23:32 -0400556 devCtrl->SessionMgr()->ForEachMatchingSessionOnLogicalFabric(ScopedNodeId(nodeid, devCtrl->GetFabricIndex()),
557 [](auto * session) {
558 if (session->IsActiveSession())
559 {
560 session->MarkAsDefunct();
561 }
562 });
Jerry Johns0eed15d2022-08-01 17:56:38 -0700563
Song GUOb9d32ec2022-10-24 14:40:11 +0800564 return ToPyChipError(CHIP_NO_ERROR);
Damian Królik88cd7662021-07-17 01:00:54 +0200565}
Andrei Litvin5a288652022-03-11 16:23:36 -0500566
Song GUOb9d32ec2022-10-24 14:40:11 +0800567PyChipError pychip_DeviceController_EstablishPASESessionIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
C Freeman5d2beb72023-07-12 18:23:50 -0400568 uint32_t setupPINCode, chip::NodeId nodeid, uint16_t port)
C Freemanaa719692021-12-03 11:45:30 -0500569{
570 chip::Inet::IPAddress peerAddr;
571 chip::Transport::PeerAddress addr;
572 RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode);
Song GUOb9d32ec2022-10-24 14:40:11 +0800573 VerifyOrReturnError(chip::Inet::IPAddress::FromString(peerAddrStr, peerAddr), ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
Andrei Litvine68bd6c2022-02-11 11:29:49 -0500574 addr.SetTransportType(chip::Transport::Type::kUdp).SetIPAddress(peerAddr);
C Freeman5d2beb72023-07-12 18:23:50 -0400575 if (port != 0)
576 {
577 addr.SetPort(port);
578 }
C Freemanaa719692021-12-03 11:45:30 -0500579 params.SetPeerAddress(addr).SetDiscriminator(0);
Terence Hampson11c0cdf2023-02-09 12:40:19 -0500580 sPairingDelegate.SetExpectingPairingComplete(true);
Song GUOb9d32ec2022-10-24 14:40:11 +0800581 return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, params));
C Freemanaa719692021-12-03 11:45:30 -0500582}
Jerry Johns71da6502022-12-11 19:32:16 -0800583
584PyChipError pychip_DeviceController_EstablishPASESessionBLE(chip::Controller::DeviceCommissioner * devCtrl, uint32_t setupPINCode,
585 uint16_t discriminator, chip::NodeId nodeid)
586{
587 chip::Transport::PeerAddress addr;
588 RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode);
589 addr.SetTransportType(chip::Transport::Type::kBle);
590 params.SetPeerAddress(addr).SetDiscriminator(discriminator);
Terence Hampson11c0cdf2023-02-09 12:40:19 -0500591 sPairingDelegate.SetExpectingPairingComplete(true);
Jerry Johns71da6502022-12-11 19:32:16 -0800592 return ToPyChipError(devCtrl->EstablishPASEConnection(nodeid, params));
593}
594
Song GUOb9d32ec2022-10-24 14:40:11 +0800595PyChipError pychip_DeviceController_Commission(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid)
C Freemanaa719692021-12-03 11:45:30 -0500596{
597 CommissioningParameters params;
Song GUOb9d32ec2022-10-24 14:40:11 +0800598 return ToPyChipError(devCtrl->Commission(nodeid, params));
C Freemanaa719692021-12-03 11:45:30 -0500599}
Damian Królik88cd7662021-07-17 01:00:54 +0200600
Song GUOb9d32ec2022-10-24 14:40:11 +0800601PyChipError pychip_DeviceController_DiscoverAllCommissionableNodes(chip::Controller::DeviceCommissioner * devCtrl)
cecille81850192021-05-11 21:43:14 -0400602{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200603 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kNone, static_cast<uint64_t>(0));
Song GUOb9d32ec2022-10-24 14:40:11 +0800604 return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
cecille81850192021-05-11 21:43:14 -0400605}
606
Song GUOb9d32ec2022-10-24 14:40:11 +0800607PyChipError pychip_DeviceController_DiscoverCommissionableNodesLongDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
608 uint16_t long_discriminator)
cecille81850192021-05-11 21:43:14 -0400609{
Vivien Nicolas8e40abc2021-12-16 17:12:37 +0100610 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kLongDiscriminator, long_discriminator);
Song GUOb9d32ec2022-10-24 14:40:11 +0800611 return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
C Freeman8a535282021-06-22 22:54:19 -0400612}
613
Song GUOb9d32ec2022-10-24 14:40:11 +0800614PyChipError pychip_DeviceController_DiscoverCommissionableNodesShortDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
615 uint16_t short_discriminator)
C Freeman8a535282021-06-22 22:54:19 -0400616{
Vivien Nicolas8e40abc2021-12-16 17:12:37 +0100617 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kShortDiscriminator, short_discriminator);
Song GUOb9d32ec2022-10-24 14:40:11 +0800618 return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
C Freeman8a535282021-06-22 22:54:19 -0400619}
620
Song GUOb9d32ec2022-10-24 14:40:11 +0800621PyChipError pychip_DeviceController_DiscoverCommissionableNodesVendor(chip::Controller::DeviceCommissioner * devCtrl,
622 uint16_t vendor)
C Freeman8a535282021-06-22 22:54:19 -0400623{
Vivien Nicolas8e40abc2021-12-16 17:12:37 +0100624 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kVendorId, vendor);
Song GUOb9d32ec2022-10-24 14:40:11 +0800625 return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
C Freeman8a535282021-06-22 22:54:19 -0400626}
627
Song GUOb9d32ec2022-10-24 14:40:11 +0800628PyChipError pychip_DeviceController_DiscoverCommissionableNodesDeviceType(chip::Controller::DeviceCommissioner * devCtrl,
629 uint16_t device_type)
C Freeman8a535282021-06-22 22:54:19 -0400630{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200631 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kDeviceType, device_type);
Song GUOb9d32ec2022-10-24 14:40:11 +0800632 return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
C Freeman8a535282021-06-22 22:54:19 -0400633}
634
Song GUOb9d32ec2022-10-24 14:40:11 +0800635PyChipError pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl)
C Freeman8a535282021-06-22 22:54:19 -0400636{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200637 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kCommissioningMode);
Song GUOb9d32ec2022-10-24 14:40:11 +0800638 return ToPyChipError(devCtrl->DiscoverCommissionableNodes(filter));
cecille81850192021-05-11 21:43:14 -0400639}
640
C Freeman89d538c2023-01-26 12:29:48 -0500641PyChipError pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback(
642 chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnWindowOpenCompleteFunct callback)
643{
644 sPairingDelegate.SetCommissioningWindowOpenCallback(callback);
645 return ToPyChipError(CHIP_NO_ERROR);
646}
647
Song GUOb9d32ec2022-10-24 14:40:11 +0800648PyChipError pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid,
649 uint16_t timeout, uint32_t iteration, uint16_t discriminator,
650 uint8_t optionInt)
Yufeng Wang275368c2021-08-31 17:42:23 -0700651{
Boris Zbarsky710b9d82022-03-24 16:08:47 -0400652 const auto option = static_cast<Controller::CommissioningWindowOpener::CommissioningWindowOption>(optionInt);
653 if (option == Controller::CommissioningWindowOpener::CommissioningWindowOption::kOriginalSetupCode)
654 {
Song GUOb9d32ec2022-10-24 14:40:11 +0800655 return ToPyChipError(Controller::AutoCommissioningWindowOpener::OpenBasicCommissioningWindow(
656 devCtrl, nodeid, System::Clock::Seconds16(timeout)));
Boris Zbarsky710b9d82022-03-24 16:08:47 -0400657 }
Damian Królikcb432c82022-02-12 07:38:49 +0100658
Boris Zbarsky710b9d82022-03-24 16:08:47 -0400659 if (option == Controller::CommissioningWindowOpener::CommissioningWindowOption::kTokenWithRandomPIN)
660 {
661 SetupPayload payload;
C Freeman89d538c2023-01-26 12:29:48 -0500662 auto opener =
663 Platform::New<Controller::CommissioningWindowOpener>(static_cast<chip::Controller::DeviceController *>(devCtrl));
664 PyChipError err = ToPyChipError(opener->OpenCommissioningWindow(nodeid, System::Clock::Seconds16(timeout), iteration,
665 discriminator, NullOptional, NullOptional,
666 sPairingDelegate.GetOpenWindowCallback(opener), payload));
667 return err;
Boris Zbarsky710b9d82022-03-24 16:08:47 -0400668 }
669
Song GUOb9d32ec2022-10-24 14:40:11 +0800670 return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT);
Yufeng Wang275368c2021-08-31 17:42:23 -0700671}
672
Song GUOb9d32ec2022-10-24 14:40:11 +0800673PyChipError
Song Guoe2590b82021-02-11 03:30:13 +0800674pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl,
675 chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback)
Song Guofe1eeb42020-10-30 04:17:04 +0800676{
Song Guoe2590b82021-02-11 03:30:13 +0800677 sPairingDelegate.SetKeyExchangeCallback(callback);
Song GUOb9d32ec2022-10-24 14:40:11 +0800678 return ToPyChipError(CHIP_NO_ERROR);
Song Guofe1eeb42020-10-30 04:17:04 +0800679}
680
Song GUOb9d32ec2022-10-24 14:40:11 +0800681PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback(
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400682 chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback)
683{
684 sPairingDelegate.SetCommissioningCompleteCallback(callback);
Song GUOb9d32ec2022-10-24 14:40:11 +0800685 return ToPyChipError(CHIP_NO_ERROR);
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400686}
687
Song GUOb9d32ec2022-10-24 14:40:11 +0800688PyChipError pychip_ScriptDevicePairingDelegate_SetCommissioningStatusUpdateCallback(
C Freemanc3b18102022-04-04 16:17:09 -0400689 chip::Controller::DeviceCommissioner * devCtrl,
690 chip::Controller::DevicePairingDelegate_OnCommissioningStatusUpdateFunct callback)
691{
692 sPairingDelegate.SetCommissioningStatusUpdateCallback(callback);
Song GUOb9d32ec2022-10-24 14:40:11 +0800693 return ToPyChipError(CHIP_NO_ERROR);
C Freemanc3b18102022-04-04 16:17:09 -0400694}
695
Kevin Schoedel57874d42021-07-20 21:10:00 -0400696const char * pychip_Stack_ErrorToString(ChipError::StorageType err)
yunhanw-google90ea3142020-10-01 13:53:26 -0700697{
Kevin Schoedel57874d42021-07-20 21:10:00 -0400698 return chip::ErrorStr(CHIP_ERROR(err));
yunhanw-google90ea3142020-10-01 13:53:26 -0700699}
700
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500701const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t statusCode)
yunhanw-google90ea3142020-10-01 13:53:26 -0700702{
703 // return chip::StatusReportStr(profileId, statusCode);
Andrei Litvin697b1552022-04-06 10:45:26 -1000704 return nullptr;
yunhanw-google90ea3142020-10-01 13:53:26 -0700705}
706
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400707namespace {
Terence Hampsonb6859d72022-08-05 13:48:11 -0400708
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400709struct GetDeviceCallbacks
710{
711 GetDeviceCallbacks(DeviceAvailableFunc callback) :
712 mOnSuccess(OnDeviceConnectedFn, this), mOnFailure(OnConnectionFailureFn, this), mCallback(callback)
713 {}
714
Marcos Bcae63192023-01-13 14:53:14 -0700715 static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400716 {
Terence Hampsonb6859d72022-08-05 13:48:11 -0400717 auto * self = static_cast<GetDeviceCallbacks *>(context);
718 auto * operationalDeviceProxy = new OperationalDeviceProxy(&exchangeMgr, sessionHandle);
Song GUOb9d32ec2022-10-24 14:40:11 +0800719 self->mCallback(operationalDeviceProxy, ToPyChipError(CHIP_NO_ERROR));
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400720 delete self;
721 }
722
Jerry Johnsd94cbdc2022-07-26 08:07:06 -0700723 static void OnConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error)
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400724 {
725 auto * self = static_cast<GetDeviceCallbacks *>(context);
Song GUOb9d32ec2022-10-24 14:40:11 +0800726 self->mCallback(nullptr, ToPyChipError(error));
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400727 delete self;
728 }
729
730 Callback::Callback<OnDeviceConnected> mOnSuccess;
731 Callback::Callback<OnDeviceConnectionFailure> mOnFailure;
732 DeviceAvailableFunc mCallback;
733};
734} // anonymous namespace
735
Song GUOb9d32ec2022-10-24 14:40:11 +0800736PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
737 DeviceAvailableFunc callback)
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400738{
Song GUOb9d32ec2022-10-24 14:40:11 +0800739 VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400740 auto * callbacks = new GetDeviceCallbacks(callback);
Song GUOb9d32ec2022-10-24 14:40:11 +0800741 return ToPyChipError(devCtrl->GetConnectedDevice(nodeId, &callbacks->mOnSuccess, &callbacks->mOnFailure));
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400742}
743
Song GUOb9d32ec2022-10-24 14:40:11 +0800744PyChipError pychip_FreeOperationalDeviceProxy(chip::OperationalDeviceProxy * deviceProxy)
Terence Hampsonb6859d72022-08-05 13:48:11 -0400745{
746 if (deviceProxy != nullptr)
747 {
748 delete deviceProxy;
749 }
Song GUOb9d32ec2022-10-24 14:40:11 +0800750 return ToPyChipError(CHIP_NO_ERROR);
Terence Hampsonb6859d72022-08-05 13:48:11 -0400751}
752
Song GUOb9d32ec2022-10-24 14:40:11 +0800753PyChipError pychip_GetLocalSessionId(chip::OperationalDeviceProxy * deviceProxy, uint16_t * localSessionId)
Jerry Johns6aa835e2022-08-28 00:11:35 -0400754{
Song GUOb9d32ec2022-10-24 14:40:11 +0800755 VerifyOrReturnError(deviceProxy->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION));
756 VerifyOrReturnError(localSessionId != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
Jerry Johns6aa835e2022-08-28 00:11:35 -0400757
758 *localSessionId = deviceProxy->GetSecureSession().Value()->AsSecureSession()->GetLocalSessionId();
Song GUOb9d32ec2022-10-24 14:40:11 +0800759 return ToPyChipError(CHIP_NO_ERROR);
Jerry Johns6aa835e2022-08-28 00:11:35 -0400760}
761
Song GUOb9d32ec2022-10-24 14:40:11 +0800762PyChipError pychip_GetNumSessionsToPeer(chip::OperationalDeviceProxy * deviceProxy, uint32_t * numSessions)
Jerry Johns6aa835e2022-08-28 00:11:35 -0400763{
Song GUOb9d32ec2022-10-24 14:40:11 +0800764 VerifyOrReturnError(deviceProxy->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION));
765 VerifyOrReturnError(numSessions != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
Jerry Johns6aa835e2022-08-28 00:11:35 -0400766
767 *numSessions = 0;
768 deviceProxy->GetExchangeManager()->GetSessionManager()->ForEachMatchingSession(
769 deviceProxy->GetPeerScopedNodeId(), [numSessions](auto * session) { (*numSessions)++; });
770
Song GUOb9d32ec2022-10-24 14:40:11 +0800771 return ToPyChipError(CHIP_NO_ERROR);
Jerry Johns6aa835e2022-08-28 00:11:35 -0400772}
773
C Freeman83ecf9c2023-06-02 18:32:53 -0400774PyChipError pychip_GetAttestationChallenge(chip::OperationalDeviceProxy * deviceProxy, uint8_t * buf, size_t * size)
775{
776 VerifyOrReturnError(deviceProxy->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION));
777 VerifyOrReturnError(buf != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
778
779 ByteSpan challenge = deviceProxy->GetSecureSession().Value()->AsSecureSession()->GetCryptoContext().GetAttestationChallenge();
780 VerifyOrReturnError(challenge.size() <= *size, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
781 memcpy(buf, challenge.data(), challenge.size());
782 *size = challenge.size();
783
784 return ToPyChipError(CHIP_NO_ERROR);
785}
786
Song GUOb9d32ec2022-10-24 14:40:11 +0800787PyChipError pychip_GetDeviceBeingCommissioned(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
788 CommissioneeDeviceProxy ** proxy)
C Freeman2bd6bd62021-11-29 12:36:33 -0500789{
Song GUOb9d32ec2022-10-24 14:40:11 +0800790 return ToPyChipError(devCtrl->GetDeviceBeingCommissioned(nodeId, proxy));
C Freeman2bd6bd62021-11-29 12:36:33 -0500791}
792
Tennessee Carmel-Veilleuxc3cd0042022-07-08 13:49:30 -0400793// This is a method called VERY seldom, just for RemoveFabric/UpdateNOC
Song GUOb9d32ec2022-10-24 14:40:11 +0800794PyChipError pychip_ExpireSessions(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId)
Tennessee Carmel-Veilleuxc3cd0042022-07-08 13:49:30 -0400795{
Song GUOb9d32ec2022-10-24 14:40:11 +0800796 VerifyOrReturnError((devCtrl != nullptr) && (devCtrl->SessionMgr() != nullptr), ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT));
Jerry Johns0eed15d2022-08-01 17:56:38 -0700797
798 //
Jerry Johns71da6502022-12-11 19:32:16 -0800799 // Stop any active pairing sessions to this node.
800 //
801 devCtrl->StopPairing(nodeId);
802
803 //
Jerry Johns0eed15d2022-08-01 17:56:38 -0700804 // Since we permit multiple controllers on the same fabric each associated with a different fabric index, expiring a session
805 // needs to correctly expire sessions on other controllers on matching fabrics as well.
806 //
807 devCtrl->SessionMgr()->ExpireAllSessionsOnLogicalFabric(ScopedNodeId(nodeId, devCtrl->GetFabricIndex()));
Song GUOb9d32ec2022-10-24 14:40:11 +0800808 return ToPyChipError(CHIP_NO_ERROR);
Tennessee Carmel-Veilleuxc3cd0042022-07-08 13:49:30 -0400809}
810
Song GUOb9d32ec2022-10-24 14:40:11 +0800811PyChipError pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::DeviceCommissioner * devCtrl)
Song Guo87142e02021-04-21 09:00:00 +0800812{
813#if CONFIG_NETWORK_LAYER_BLE
Michael Spang63870492022-06-28 08:41:08 -0400814 devCtrl->CloseBleConnection();
Song GUOb9d32ec2022-10-24 14:40:11 +0800815 return ToPyChipError(CHIP_NO_ERROR);
Song Guo87142e02021-04-21 09:00:00 +0800816#else
Song GUOb9d32ec2022-10-24 14:40:11 +0800817 return ToPyChipError(CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
Song Guo87142e02021-04-21 09:00:00 +0800818#endif
819}
820
Pankaj Garga04576d2021-11-08 15:04:13 -0800821uint64_t pychip_GetCommandSenderHandle(chip::DeviceProxy * device)
Song Guo9ab3c902021-04-09 06:08:35 +0800822{
Song Guo8d7486f2021-05-17 23:11:39 +0800823 return 0;
Song Guo9ab3c902021-04-09 06:08:35 +0800824}
825
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500826void pychip_Stack_SetLogFunct(LogMessageFunct logFunct)
yunhanw-google90ea3142020-10-01 13:53:26 -0700827{
Andrei Litvin0a91b1b2021-02-08 09:31:24 -0500828 // TODO: determine if log redirection is supposed to be functioning in CHIP
829 //
830 // Background: original log baseline supported 'redirect logs to this
831 // function' however CHIP does not currently provide this.
832 //
833 // Ideally log redirection should work so that python code can do things
834 // like using the log module.
yunhanw-google90ea3142020-10-01 13:53:26 -0700835}
Song GUOed3b2332021-07-21 02:12:40 +0800836
Song GUOb9d32ec2022-10-24 14:40:11 +0800837PyChipError pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext)
Song GUOed3b2332021-07-21 02:12:40 +0800838{
839 if (callback == nullptr || pythonContext == nullptr)
840 {
Song GUOb9d32ec2022-10-24 14:40:11 +0800841 return ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT);
Song GUOed3b2332021-07-21 02:12:40 +0800842 }
Song GUOed3b2332021-07-21 02:12:40 +0800843 PlatformMgr().ScheduleWork(callback, reinterpret_cast<intptr_t>(pythonContext));
Song GUOb9d32ec2022-10-24 14:40:11 +0800844 return ToPyChipError(CHIP_NO_ERROR);
Song GUOed3b2332021-07-21 02:12:40 +0800845}