blob: 402d8cfb1ab31c1626b8d3c44c61f3065ce1c125 [file] [log] [blame]
yunhanw-google90ea3142020-10-01 13:53:26 -07001/*
2 *
Kevin Schoedela8681872021-01-28 15:53:13 -05003 * Copyright (c) 2020-2021 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
Damian Królika5784162021-03-05 16:56:42 +010043#include "ChipDeviceController-ScriptDeviceAddressUpdateDelegate.h"
Song Guofe1eeb42020-10-30 04:17:04 +080044#include "ChipDeviceController-ScriptDevicePairingDelegate.h"
Song Guo830d1f82020-12-10 01:59:07 +080045#include "ChipDeviceController-StorageDelegate.h"
Song Guofe1eeb42020-10-30 04:17:04 +080046
Song Guo9ab3c902021-04-09 06:08:35 +080047#include "chip/interaction_model/Delegate.h"
48
Song Guoa77a6622021-01-29 13:13:02 +080049#include <app/CommandSender.h>
50#include <app/InteractionModelEngine.h>
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +020051#include <app/server/Dnssd.h>
Song Guoa77a6622021-01-29 13:13:02 +080052#include <controller/CHIPDevice.h>
Song Guoe2590b82021-02-11 03:30:13 +080053#include <controller/CHIPDeviceController.h>
Sagar Dhawanae69dd72021-09-29 15:13:09 -070054#include <controller/CHIPDeviceControllerFactory.h>
Pankaj Garg0238a6c2021-05-10 07:33:19 -070055#include <controller/ExampleOperationalCredentialsIssuer.h>
Marty Leisner0e529702021-09-27 10:55:08 -040056#include <credentials/DeviceAttestationVerifier.h>
57#include <credentials/examples/DeviceAttestationVerifierExample.h>
cecille81850192021-05-11 21:43:14 -040058#include <inet/IPAddress.h>
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +020059#include <lib/dnssd/Resolver.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080060#include <lib/support/BytesToHex.h>
61#include <lib/support/CHIPMem.h>
62#include <lib/support/CodeUtils.h>
63#include <lib/support/DLLUtil.h>
64#include <lib/support/ScopedBuffer.h>
65#include <lib/support/logging/CHIPLogging.h>
Song GUOed3b2332021-07-21 02:12:40 +080066#include <platform/CHIPDeviceLayer.h>
cecille81850192021-05-11 21:43:14 -040067#include <setup_payload/QRCodeSetupPayloadParser.h>
yunhanw-google90ea3142020-10-01 13:53:26 -070068
Song Guo830d1f82020-12-10 01:59:07 +080069using namespace chip;
yunhanw-google90ea3142020-10-01 13:53:26 -070070using namespace chip::Ble;
Song Guoe2590b82021-02-11 03:30:13 +080071using namespace chip::Controller;
Marty Leisner0e529702021-09-27 10:55:08 -040072using namespace chip::Credentials;
Song GUOed3b2332021-07-21 02:12:40 +080073using namespace chip::DeviceLayer;
yunhanw-google90ea3142020-10-01 13:53:26 -070074
Kevin Schoedel57874d42021-07-20 21:10:00 -040075static_assert(std::is_same<uint32_t, ChipError::StorageType>::value, "python assumes CHIP_ERROR maps to c_uint32");
76
yunhanw-google90ea3142020-10-01 13:53:26 -070077extern "C" {
yunhanw-google90ea3142020-10-01 13:53:26 -070078typedef void (*ConstructBytesArrayFunct)(const uint8_t * dataBuf, uint32_t dataLen);
79typedef void (*LogMessageFunct)(uint64_t time, uint64_t timeUS, const char * moduleName, uint8_t category, const char * msg);
Kevin Schoedel57874d42021-07-20 21:10:00 -040080typedef void (*DeviceAvailableFunc)(Device * device, ChipError::StorageType err);
Song GUOed3b2332021-07-21 02:12:40 +080081typedef void (*ChipThreadTaskRunnerFunct)(intptr_t context);
yunhanw-google90ea3142020-10-01 13:53:26 -070082}
83
Song Guoe2590b82021-02-11 03:30:13 +080084namespace {
85chip::Controller::PythonPersistentStorageDelegate sStorageDelegate;
86chip::Controller::ScriptDevicePairingDelegate sPairingDelegate;
Damian Królika5784162021-03-05 16:56:42 +010087chip::Controller::ScriptDeviceAddressUpdateDelegate sDeviceAddressUpdateDelegate;
Pankaj Garg0238a6c2021-05-10 07:33:19 -070088chip::Controller::ExampleOperationalCredentialsIssuer sOperationalCredentialsIssuer;
Song Guoe2590b82021-02-11 03:30:13 +080089} // namespace
yunhanw-google90ea3142020-10-01 13:53:26 -070090
91// NOTE: Remote device ID is in sync with the echo server device id
92// At some point, we may want to add an option to connect to a device without
93// knowing its id, because the ID can be learned on the first response that is received.
Kevin Schoedel5f19e992021-03-02 14:36:20 -050094chip::NodeId kDefaultLocalDeviceId = chip::kTestControllerNodeId;
95chip::NodeId kRemoteDeviceId = chip::kTestDeviceNodeId;
yunhanw-google90ea3142020-10-01 13:53:26 -070096
yunhanw-google90ea3142020-10-01 13:53:26 -070097extern "C" {
Kevin Schoedel57874d42021-07-20 21:10:00 -040098ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl,
99 chip::NodeId localDeviceId);
100ChipError::StorageType pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl);
101ChipError::StorageType pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCommissioner * devCtrl,
102 chip::NodeId nodeId, char * outAddress, uint64_t maxAddressLen,
103 uint16_t * outPort);
Pankaj Garg6efec202021-08-25 10:47:29 -0700104ChipError::StorageType pychip_DeviceController_GetCompressedFabricId(chip::Controller::DeviceCommissioner * devCtrl,
105 uint64_t * outFabricId);
Kevin Schoedel57874d42021-07-20 21:10:00 -0400106ChipError::StorageType pychip_DeviceController_GetFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId);
yunhanw-google90ea3142020-10-01 13:53:26 -0700107
Song Guofe1eeb42020-10-30 04:17:04 +0800108// Rendezvous
Kevin Schoedel57874d42021-07-20 21:10:00 -0400109ChipError::StorageType pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
110 uint32_t setupPINCode, chip::NodeId nodeid);
111ChipError::StorageType pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
112 uint32_t setupPINCode, chip::NodeId nodeid);
113ChipError::StorageType pychip_DeviceController_CloseSession(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid);
Song Guofe1eeb42020-10-30 04:17:04 +0800114
Kevin Schoedel57874d42021-07-20 21:10:00 -0400115ChipError::StorageType
116pychip_DeviceController_DiscoverCommissionableNodesLongDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
117 uint16_t long_discriminator);
118ChipError::StorageType pychip_DeviceController_DiscoverAllCommissionableNodes(chip::Controller::DeviceCommissioner * devCtrl);
C Freeman8a535282021-06-22 22:54:19 -0400119
Kevin Schoedel57874d42021-07-20 21:10:00 -0400120ChipError::StorageType
121pychip_DeviceController_DiscoverCommissionableNodesShortDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
122 uint16_t short_discriminator);
123ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesVendor(chip::Controller::DeviceCommissioner * devCtrl,
124 uint16_t vendor);
125ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesDeviceType(chip::Controller::DeviceCommissioner * devCtrl,
126 uint16_t device_type);
127ChipError::StorageType
chrisdecenzo97d9f7e2021-09-14 10:37:29 -0700128pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl);
Kevin Schoedel57874d42021-07-20 21:10:00 -0400129ChipError::StorageType pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext);
Song GUOed3b2332021-07-21 02:12:40 +0800130
Yufeng Wang275368c2021-08-31 17:42:23 -0700131ChipError::StorageType pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl,
132 chip::NodeId nodeid, uint16_t timeout, uint16_t iteration,
133 uint16_t discriminator, uint8_t option);
134
cecille81850192021-05-11 21:43:14 -0400135void pychip_DeviceController_PrintDiscoveredDevices(chip::Controller::DeviceCommissioner * devCtrl);
136bool pychip_DeviceController_GetIPForDiscoveredDevice(chip::Controller::DeviceCommissioner * devCtrl, int idx, char * addrStr,
137 uint32_t len);
138
Song Guoe2590b82021-02-11 03:30:13 +0800139// Pairing Delegate
Kevin Schoedel57874d42021-07-20 21:10:00 -0400140ChipError::StorageType
Song Guoe2590b82021-02-11 03:30:13 +0800141pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl,
142 chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback);
Song Guofe1eeb42020-10-30 04:17:04 +0800143
Kevin Schoedel57874d42021-07-20 21:10:00 -0400144ChipError::StorageType pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback(
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400145 chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback);
146
Damian Królika5784162021-03-05 16:56:42 +0100147void pychip_ScriptDeviceAddressUpdateDelegate_SetOnAddressUpdateComplete(
148 chip::Controller::DeviceAddressUpdateDelegate_OnUpdateComplete callback);
Kevin Schoedel57874d42021-07-20 21:10:00 -0400149ChipError::StorageType pychip_Resolver_ResolveNode(uint64_t fabricid, chip::NodeId nodeid);
Damian Królika5784162021-03-05 16:56:42 +0100150
Song Guo87142e02021-04-21 09:00:00 +0800151// BLE
Kevin Schoedel57874d42021-07-20 21:10:00 -0400152ChipError::StorageType pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::DeviceCommissioner * devCtrl);
Song Guo87142e02021-04-21 09:00:00 +0800153
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500154uint8_t pychip_DeviceController_GetLogFilter();
155void pychip_DeviceController_SetLogFilter(uint8_t category);
yunhanw-google90ea3142020-10-01 13:53:26 -0700156
Kevin Schoedel57874d42021-07-20 21:10:00 -0400157ChipError::StorageType pychip_Stack_Init();
158ChipError::StorageType pychip_Stack_Shutdown();
159const char * pychip_Stack_ErrorToString(ChipError::StorageType err);
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500160const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t statusCode);
161void pychip_Stack_SetLogFunct(LogMessageFunct logFunct);
Song Guoa77a6622021-01-29 13:13:02 +0800162
Kevin Schoedel57874d42021-07-20 21:10:00 -0400163ChipError::StorageType pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
164 DeviceAvailableFunc callback);
Song Guo9ab3c902021-04-09 06:08:35 +0800165uint64_t pychip_GetCommandSenderHandle(chip::Controller::Device * device);
Song Guobbcc3762021-03-10 07:08:52 +0800166// CHIP Stack objects
Kevin Schoedel57874d42021-07-20 21:10:00 -0400167ChipError::StorageType pychip_BLEMgrImpl_ConfigureBle(uint32_t bluetoothAdapterId);
Song GUO75f38952021-10-13 04:13:10 +0800168
169chip::ChipError::StorageType pychip_InteractionModel_ShutdownSubscription(uint64_t subscriptionId);
yunhanw-google90ea3142020-10-01 13:53:26 -0700170}
171
Kevin Schoedel57874d42021-07-20 21:10:00 -0400172ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl,
173 chip::NodeId localDeviceId)
yunhanw-google90ea3142020-10-01 13:53:26 -0700174{
Song Guoe2590b82021-02-11 03:30:13 +0800175 *outDevCtrl = new chip::Controller::DeviceCommissioner();
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400176 VerifyOrReturnError(*outDevCtrl != NULL, CHIP_ERROR_NO_MEMORY.AsInteger());
yunhanw-google90ea3142020-10-01 13:53:26 -0700177
Kevin Schoedel5f19e992021-03-02 14:36:20 -0500178 if (localDeviceId == chip::kUndefinedNodeId)
179 {
180 localDeviceId = kDefaultLocalDeviceId;
181 }
Song Guo9ab3c902021-04-09 06:08:35 +0800182
Marty Leisner0e529702021-09-27 10:55:08 -0400183 // Initialize device attestation verifier
184 SetDeviceAttestationVerifier(Examples::GetExampleDACVerifier());
185
Kevin Schoedel57874d42021-07-20 21:10:00 -0400186 CHIP_ERROR err = sOperationalCredentialsIssuer.Initialize(sStorageDelegate);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400187 VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
Pankaj Garg0238a6c2021-05-10 07:33:19 -0700188
Pankaj Garg7b000572021-08-13 20:14:29 -0700189 chip::Crypto::P256Keypair ephemeralKey;
190 err = ephemeralKey.Initialize();
191 VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
192
193 chip::Platform::ScopedMemoryBuffer<uint8_t> noc;
194 ReturnErrorCodeIf(!noc.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger());
195 MutableByteSpan nocSpan(noc.Get(), kMaxCHIPDERCertLength);
196
197 chip::Platform::ScopedMemoryBuffer<uint8_t> icac;
198 ReturnErrorCodeIf(!icac.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger());
199 MutableByteSpan icacSpan(icac.Get(), kMaxCHIPDERCertLength);
200
201 chip::Platform::ScopedMemoryBuffer<uint8_t> rcac;
202 ReturnErrorCodeIf(!rcac.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger());
203 MutableByteSpan rcacSpan(rcac.Get(), kMaxCHIPDERCertLength);
204
205 err = sOperationalCredentialsIssuer.GenerateNOCChainAfterValidation(localDeviceId, 0, ephemeralKey.Pubkey(), rcacSpan, icacSpan,
206 nocSpan);
207 VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
208
Sagar Dhawanae69dd72021-09-29 15:13:09 -0700209 FactoryInitParams factoryParams;
210 factoryParams.storageDelegate = &sStorageDelegate;
211 factoryParams.imDelegate = &PythonInteractionModelDelegate::Instance();
212
213 SetupParams initParams;
214 initParams.deviceAddressUpdateDelegate = &sDeviceAddressUpdateDelegate;
Song Guo80120a22021-05-11 23:04:52 +0800215 initParams.pairingDelegate = &sPairingDelegate;
Pankaj Garg0238a6c2021-05-10 07:33:19 -0700216 initParams.operationalCredentialsDelegate = &sOperationalCredentialsIssuer;
Pankaj Garg7b000572021-08-13 20:14:29 -0700217 initParams.ephemeralKeypair = &ephemeralKey;
218 initParams.controllerRCAC = rcacSpan;
219 initParams.controllerICAC = icacSpan;
220 initParams.controllerNOC = nocSpan;
Song Guo9ab3c902021-04-09 06:08:35 +0800221
Sagar Dhawanae69dd72021-09-29 15:13:09 -0700222 ReturnErrorOnFailure(DeviceControllerFactory::GetInstance().Init(factoryParams).AsInteger());
223 err = DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, **outDevCtrl);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400224 VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
Sharad Binjola535feb02021-09-15 17:37:57 -0700225#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200226 chip::app::DnssdServer::Instance().StartServer(chip::Dnssd::CommissioningMode::kDisabled);
Sharad Binjola535feb02021-09-15 17:37:57 -0700227#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
yunhanw-google90ea3142020-10-01 13:53:26 -0700228
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400229 return CHIP_NO_ERROR.AsInteger();
yunhanw-google90ea3142020-10-01 13:53:26 -0700230}
231
Kevin Schoedel57874d42021-07-20 21:10:00 -0400232ChipError::StorageType pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl)
yunhanw-google90ea3142020-10-01 13:53:26 -0700233{
234 if (devCtrl != NULL)
235 {
236 devCtrl->Shutdown();
237 delete devCtrl;
238 }
Damian Królika5784162021-03-05 16:56:42 +0100239
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400240 return CHIP_NO_ERROR.AsInteger();
Damian Królika5784162021-03-05 16:56:42 +0100241}
242
Kevin Schoedel57874d42021-07-20 21:10:00 -0400243ChipError::StorageType pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCommissioner * devCtrl,
244 chip::NodeId nodeId, char * outAddress, uint64_t maxAddressLen,
245 uint16_t * outPort)
Damian Królika5784162021-03-05 16:56:42 +0100246{
Damian Królika5784162021-03-05 16:56:42 +0100247 Inet::IPAddress address;
Pankaj Gargfee3d262021-10-17 19:31:32 -0700248 ReturnErrorOnFailure(
249 devCtrl
250 ->GetPeerAddressAndPort(PeerId().SetCompressedFabricId(devCtrl->GetCompressedFabricId()).SetNodeId(nodeId), address,
251 *outPort)
252 .AsInteger());
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400253 VerifyOrReturnError(address.ToString(outAddress, maxAddressLen), CHIP_ERROR_BUFFER_TOO_SMALL.AsInteger());
Damian Królika5784162021-03-05 16:56:42 +0100254
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400255 return CHIP_NO_ERROR.AsInteger();
yunhanw-google90ea3142020-10-01 13:53:26 -0700256}
257
Pankaj Garg6efec202021-08-25 10:47:29 -0700258ChipError::StorageType pychip_DeviceController_GetCompressedFabricId(chip::Controller::DeviceCommissioner * devCtrl,
259 uint64_t * outFabricId)
260{
261 *outFabricId = devCtrl->GetCompressedFabricId();
262 return CHIP_NO_ERROR.AsInteger();
263}
264
Kevin Schoedel57874d42021-07-20 21:10:00 -0400265ChipError::StorageType pychip_DeviceController_GetFabricId(chip::Controller::DeviceCommissioner * devCtrl, uint64_t * outFabricId)
Yufeng Wangb728b742021-06-16 08:04:17 -0700266{
Pankaj Garg6efec202021-08-25 10:47:29 -0700267 *outFabricId = devCtrl->GetFabricId();
268 return CHIP_NO_ERROR.AsInteger();
Yufeng Wangb728b742021-06-16 08:04:17 -0700269}
270
Kevin Schoedel57874d42021-07-20 21:10:00 -0400271const char * pychip_DeviceController_ErrorToString(ChipError::StorageType err)
yunhanw-google90ea3142020-10-01 13:53:26 -0700272{
Kevin Schoedel57874d42021-07-20 21:10:00 -0400273 return chip::ErrorStr(CHIP_ERROR(err));
yunhanw-google90ea3142020-10-01 13:53:26 -0700274}
275
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500276const char * pychip_DeviceController_StatusReportToString(uint32_t profileId, uint16_t statusCode)
yunhanw-google90ea3142020-10-01 13:53:26 -0700277{
278 // return chip::StatusReportStr(profileId, statusCode);
279 return NULL;
280}
281
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500282uint8_t pychip_DeviceController_GetLogFilter()
yunhanw-google90ea3142020-10-01 13:53:26 -0700283{
284#if _CHIP_USE_LOGGING
285 return chip::Logging::GetLogFilter();
286#else
287 return chip::Logging::kLogCategory_None;
288#endif
289}
290
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500291void pychip_DeviceController_SetLogFilter(uint8_t category)
yunhanw-google90ea3142020-10-01 13:53:26 -0700292{
293#if _CHIP_USE_LOGGING
294 chip::Logging::SetLogFilter(category);
295#endif
296}
297
Kevin Schoedel57874d42021-07-20 21:10:00 -0400298ChipError::StorageType pychip_DeviceController_ConnectBLE(chip::Controller::DeviceCommissioner * devCtrl, uint16_t discriminator,
299 uint32_t setupPINCode, chip::NodeId nodeid)
Song Guofe1eeb42020-10-30 04:17:04 +0800300{
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400301 return devCtrl
302 ->PairDevice(nodeid,
303 chip::RendezvousParameters()
304 .SetPeerAddress(Transport::PeerAddress(Transport::Type::kBle))
305 .SetSetupPINCode(setupPINCode)
306 .SetDiscriminator(discriminator))
307 .AsInteger();
Song Guob94c9802021-01-29 13:58:48 +0800308}
309
Kevin Schoedel57874d42021-07-20 21:10:00 -0400310ChipError::StorageType pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissioner * devCtrl, const char * peerAddrStr,
311 uint32_t setupPINCode, chip::NodeId nodeid)
Song Guo830d1f82020-12-10 01:59:07 +0800312{
Song Guo830d1f82020-12-10 01:59:07 +0800313 chip::Inet::IPAddress peerAddr;
314 chip::Transport::PeerAddress addr;
315 chip::RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode);
316
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400317 VerifyOrReturnError(chip::Inet::IPAddress::FromString(peerAddrStr, peerAddr), CHIP_ERROR_INVALID_ARGUMENT.AsInteger());
Song Guo830d1f82020-12-10 01:59:07 +0800318 // TODO: IP rendezvous should use TCP connection.
319 addr.SetTransportType(chip::Transport::Type::kUdp).SetIPAddress(peerAddr);
320 params.SetPeerAddress(addr).SetDiscriminator(0);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400321 return devCtrl->PairDevice(nodeid, params).AsInteger();
Song Guofe1eeb42020-10-30 04:17:04 +0800322}
323
Pankaj Gargfee3d262021-10-17 19:31:32 -0700324void CloseSessionCallback(Device * device, ChipError::StorageType err)
325{
326 if (device != nullptr)
327 {
328 device->CloseSession();
329 }
330 if (!ChipError::IsSuccess(err))
331 {
332 ChipLogError(Controller, "Close session callback was called with an error: %d", err);
333 }
334}
335
Kevin Schoedel57874d42021-07-20 21:10:00 -0400336ChipError::StorageType pychip_DeviceController_CloseSession(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid)
Damian Królik88cd7662021-07-17 01:00:54 +0200337{
Pankaj Gargfee3d262021-10-17 19:31:32 -0700338 return pychip_GetConnectedDeviceByNodeId(devCtrl, nodeid, CloseSessionCallback);
Damian Królik88cd7662021-07-17 01:00:54 +0200339}
340
Kevin Schoedel57874d42021-07-20 21:10:00 -0400341ChipError::StorageType pychip_DeviceController_DiscoverAllCommissionableNodes(chip::Controller::DeviceCommissioner * devCtrl)
cecille81850192021-05-11 21:43:14 -0400342{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200343 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kNone, static_cast<uint64_t>(0));
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400344 return devCtrl->DiscoverCommissionableNodes(filter).AsInteger();
cecille81850192021-05-11 21:43:14 -0400345}
346
Kevin Schoedel57874d42021-07-20 21:10:00 -0400347ChipError::StorageType
348pychip_DeviceController_DiscoverCommissionableNodesLongDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
349 uint16_t long_discriminator)
cecille81850192021-05-11 21:43:14 -0400350{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200351 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kLong, long_discriminator);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400352 return devCtrl->DiscoverCommissionableNodes(filter).AsInteger();
C Freeman8a535282021-06-22 22:54:19 -0400353}
354
Kevin Schoedel57874d42021-07-20 21:10:00 -0400355ChipError::StorageType
356pychip_DeviceController_DiscoverCommissionableNodesShortDiscriminator(chip::Controller::DeviceCommissioner * devCtrl,
357 uint16_t short_discriminator)
C Freeman8a535282021-06-22 22:54:19 -0400358{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200359 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kShort, short_discriminator);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400360 return devCtrl->DiscoverCommissionableNodes(filter).AsInteger();
C Freeman8a535282021-06-22 22:54:19 -0400361}
362
Kevin Schoedel57874d42021-07-20 21:10:00 -0400363ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesVendor(chip::Controller::DeviceCommissioner * devCtrl,
364 uint16_t vendor)
C Freeman8a535282021-06-22 22:54:19 -0400365{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200366 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kVendor, vendor);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400367 return devCtrl->DiscoverCommissionableNodes(filter).AsInteger();
C Freeman8a535282021-06-22 22:54:19 -0400368}
369
Kevin Schoedel57874d42021-07-20 21:10:00 -0400370ChipError::StorageType pychip_DeviceController_DiscoverCommissionableNodesDeviceType(chip::Controller::DeviceCommissioner * devCtrl,
371 uint16_t device_type)
C Freeman8a535282021-06-22 22:54:19 -0400372{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200373 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kDeviceType, device_type);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400374 return devCtrl->DiscoverCommissionableNodes(filter).AsInteger();
C Freeman8a535282021-06-22 22:54:19 -0400375}
376
Kevin Schoedel57874d42021-07-20 21:10:00 -0400377ChipError::StorageType
chrisdecenzo97d9f7e2021-09-14 10:37:29 -0700378pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled(chip::Controller::DeviceCommissioner * devCtrl)
C Freeman8a535282021-06-22 22:54:19 -0400379{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200380 Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kCommissioningMode);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400381 return devCtrl->DiscoverCommissionableNodes(filter).AsInteger();
cecille81850192021-05-11 21:43:14 -0400382}
383
Yufeng Wang275368c2021-08-31 17:42:23 -0700384ChipError::StorageType pychip_DeviceController_OpenCommissioningWindow(chip::Controller::DeviceCommissioner * devCtrl,
385 chip::NodeId nodeid, uint16_t timeout, uint16_t iteration,
386 uint16_t discriminator, uint8_t option)
387{
388 return devCtrl->OpenCommissioningWindow(nodeid, timeout, iteration, discriminator, option).AsInteger();
389}
390
cecille81850192021-05-11 21:43:14 -0400391void pychip_DeviceController_PrintDiscoveredDevices(chip::Controller::DeviceCommissioner * devCtrl)
392{
393 for (int i = 0; i < devCtrl->GetMaxCommissionableNodesSupported(); ++i)
394 {
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200395 const chip::Dnssd::DiscoveredNodeData * dnsSdInfo = devCtrl->GetDiscoveredDevice(i);
cecille81850192021-05-11 21:43:14 -0400396 if (dnsSdInfo == nullptr)
397 {
398 continue;
399 }
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200400 char rotatingId[chip::Dnssd::kMaxRotatingIdLen * 2 + 1] = "";
C Freemanb5eade02021-06-02 16:36:56 -0400401 Encoding::BytesToUppercaseHexString(dnsSdInfo->rotatingId, dnsSdInfo->rotatingIdLen, rotatingId, sizeof(rotatingId));
402
Sharad Binjolab2f8af02021-06-29 09:13:13 -0700403 ChipLogProgress(Discovery, "Commissionable Node %d", i);
cecille81850192021-05-11 21:43:14 -0400404 ChipLogProgress(Discovery, "\tHost name:\t\t%s", dnsSdInfo->hostName);
chrisdecenzo97d9f7e2021-09-14 10:37:29 -0700405 ChipLogProgress(Discovery, "\tPort:\t\t\t%u", dnsSdInfo->port);
cecille81850192021-05-11 21:43:14 -0400406 ChipLogProgress(Discovery, "\tLong discriminator:\t%u", dnsSdInfo->longDiscriminator);
407 ChipLogProgress(Discovery, "\tVendor ID:\t\t%u", dnsSdInfo->vendorId);
408 ChipLogProgress(Discovery, "\tProduct ID:\t\t%u", dnsSdInfo->productId);
C Freemanb5eade02021-06-02 16:36:56 -0400409 ChipLogProgress(Discovery, "\tCommissioning Mode\t%u", dnsSdInfo->commissioningMode);
410 ChipLogProgress(Discovery, "\tDevice Type\t\t%u", dnsSdInfo->deviceType);
411 ChipLogProgress(Discovery, "\tDevice Name\t\t%s", dnsSdInfo->deviceName);
412 ChipLogProgress(Discovery, "\tRotating Id\t\t%s", rotatingId);
413 ChipLogProgress(Discovery, "\tPairing Instruction\t%s", dnsSdInfo->pairingInstruction);
414 ChipLogProgress(Discovery, "\tPairing Hint\t\t0x%x", dnsSdInfo->pairingHint);
C Freemancb511ba2021-09-17 10:44:32 -0400415 if (dnsSdInfo->GetMrpRetryIntervalIdle().HasValue())
416 {
417 ChipLogProgress(Discovery, "\tMrp Interval idle\t%u", dnsSdInfo->GetMrpRetryIntervalIdle().Value());
418 }
419 else
420 {
421 ChipLogProgress(Discovery, "\tMrp Interval idle\tNot present");
422 }
423 if (dnsSdInfo->GetMrpRetryIntervalActive().HasValue())
424 {
425 ChipLogProgress(Discovery, "\tMrp Interval active\t%u", dnsSdInfo->GetMrpRetryIntervalActive().Value());
426 }
427 else
428 {
429 ChipLogProgress(Discovery, "\tMrp Interval active\tNot present");
430 }
431 ChipLogProgress(Discovery, "\tSupports TCP\t\t%d", dnsSdInfo->supportsTcp);
cecille81850192021-05-11 21:43:14 -0400432 for (int j = 0; j < dnsSdInfo->numIPs; ++j)
433 {
434 char buf[chip::Inet::kMaxIPAddressStringLength];
435 dnsSdInfo->ipAddress[j].ToString(buf);
436 ChipLogProgress(Discovery, "\tAddress %d:\t\t%s", j, buf);
437 }
438 }
439}
440
441bool pychip_DeviceController_GetIPForDiscoveredDevice(chip::Controller::DeviceCommissioner * devCtrl, int idx, char * addrStr,
442 uint32_t len)
443{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200444 const chip::Dnssd::DiscoveredNodeData * dnsSdInfo = devCtrl->GetDiscoveredDevice(idx);
cecille81850192021-05-11 21:43:14 -0400445 if (dnsSdInfo == nullptr)
446 {
447 return false;
448 }
449 // TODO(cecille): Select which one we actually want.
450 if (dnsSdInfo->ipAddress[0].ToString(addrStr, len) == addrStr)
451 {
452 return true;
453 }
454 return false;
455}
456
Kevin Schoedel57874d42021-07-20 21:10:00 -0400457ChipError::StorageType
Song Guoe2590b82021-02-11 03:30:13 +0800458pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback(chip::Controller::DeviceCommissioner * devCtrl,
459 chip::Controller::DevicePairingDelegate_OnPairingCompleteFunct callback)
Song Guofe1eeb42020-10-30 04:17:04 +0800460{
Song Guoe2590b82021-02-11 03:30:13 +0800461 sPairingDelegate.SetKeyExchangeCallback(callback);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400462 return CHIP_NO_ERROR.AsInteger();
Song Guofe1eeb42020-10-30 04:17:04 +0800463}
464
Kevin Schoedel57874d42021-07-20 21:10:00 -0400465ChipError::StorageType pychip_ScriptDevicePairingDelegate_SetCommissioningCompleteCallback(
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400466 chip::Controller::DeviceCommissioner * devCtrl, chip::Controller::DevicePairingDelegate_OnCommissioningCompleteFunct callback)
467{
468 sPairingDelegate.SetCommissioningCompleteCallback(callback);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400469 return CHIP_NO_ERROR.AsInteger();
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400470}
471
Damian Królika5784162021-03-05 16:56:42 +0100472void pychip_ScriptDeviceAddressUpdateDelegate_SetOnAddressUpdateComplete(
473 chip::Controller::DeviceAddressUpdateDelegate_OnUpdateComplete callback)
474{
475 sDeviceAddressUpdateDelegate.SetOnAddressUpdateComplete(callback);
476}
477
Kevin Schoedel57874d42021-07-20 21:10:00 -0400478ChipError::StorageType pychip_Resolver_ResolveNode(uint64_t fabricid, chip::NodeId nodeid)
Damian Królika5784162021-03-05 16:56:42 +0100479{
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200480 return Dnssd::Resolver::Instance()
Pankaj Garg6efec202021-08-25 10:47:29 -0700481 .ResolveNodeId(PeerId().SetNodeId(nodeid).SetCompressedFabricId(fabricid), Inet::kIPAddressType_Any)
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400482 .AsInteger();
Damian Królika5784162021-03-05 16:56:42 +0100483}
484
Kevin Schoedel57874d42021-07-20 21:10:00 -0400485ChipError::StorageType pychip_Stack_Init()
yunhanw-google90ea3142020-10-01 13:53:26 -0700486{
487 CHIP_ERROR err = CHIP_NO_ERROR;
488
Song Guofe1eeb42020-10-30 04:17:04 +0800489 err = chip::Platform::MemoryInit();
490 SuccessOrExit(err);
491
yunhanw-google90ea3142020-10-01 13:53:26 -0700492#if !CHIP_SYSTEM_CONFIG_USE_SOCKETS
493
494 ExitNow(err = CHIP_ERROR_NOT_IMPLEMENTED);
495
496#else /* CHIP_SYSTEM_CONFIG_USE_SOCKETS */
497
yunhanw-google90ea3142020-10-01 13:53:26 -0700498#endif /* CHIP_SYSTEM_CONFIG_USE_SOCKETS */
499
500exit:
501 if (err != CHIP_NO_ERROR)
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500502 pychip_Stack_Shutdown();
yunhanw-google90ea3142020-10-01 13:53:26 -0700503
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400504 return err.AsInteger();
yunhanw-google90ea3142020-10-01 13:53:26 -0700505}
506
Kevin Schoedel57874d42021-07-20 21:10:00 -0400507ChipError::StorageType pychip_Stack_Shutdown()
yunhanw-google90ea3142020-10-01 13:53:26 -0700508{
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400509 return CHIP_NO_ERROR.AsInteger();
yunhanw-google90ea3142020-10-01 13:53:26 -0700510}
511
Kevin Schoedel57874d42021-07-20 21:10:00 -0400512const char * pychip_Stack_ErrorToString(ChipError::StorageType err)
yunhanw-google90ea3142020-10-01 13:53:26 -0700513{
Kevin Schoedel57874d42021-07-20 21:10:00 -0400514 return chip::ErrorStr(CHIP_ERROR(err));
yunhanw-google90ea3142020-10-01 13:53:26 -0700515}
516
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500517const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t statusCode)
yunhanw-google90ea3142020-10-01 13:53:26 -0700518{
519 // return chip::StatusReportStr(profileId, statusCode);
520 return NULL;
521}
522
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400523namespace {
524struct GetDeviceCallbacks
525{
526 GetDeviceCallbacks(DeviceAvailableFunc callback) :
527 mOnSuccess(OnDeviceConnectedFn, this), mOnFailure(OnConnectionFailureFn, this), mCallback(callback)
528 {}
529
530 static void OnDeviceConnectedFn(void * context, Device * device)
531 {
532 auto * self = static_cast<GetDeviceCallbacks *>(context);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400533 self->mCallback(device, CHIP_NO_ERROR.AsInteger());
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400534 delete self;
535 }
536
537 static void OnConnectionFailureFn(void * context, NodeId deviceId, CHIP_ERROR error)
538 {
539 auto * self = static_cast<GetDeviceCallbacks *>(context);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400540 self->mCallback(nullptr, error.AsInteger());
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400541 delete self;
542 }
543
544 Callback::Callback<OnDeviceConnected> mOnSuccess;
545 Callback::Callback<OnDeviceConnectionFailure> mOnFailure;
546 DeviceAvailableFunc mCallback;
547};
548} // anonymous namespace
549
Kevin Schoedel57874d42021-07-20 21:10:00 -0400550ChipError::StorageType pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId,
551 DeviceAvailableFunc callback)
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400552{
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400553 VerifyOrReturnError(devCtrl != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger());
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400554 auto * callbacks = new GetDeviceCallbacks(callback);
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400555 return devCtrl->GetConnectedDevice(nodeId, &callbacks->mOnSuccess, &callbacks->mOnFailure).AsInteger();
Boris Zbarsky39d1e922021-07-02 15:23:53 -0400556}
557
Kevin Schoedel57874d42021-07-20 21:10:00 -0400558ChipError::StorageType pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::DeviceCommissioner * devCtrl)
Song Guo87142e02021-04-21 09:00:00 +0800559{
560#if CONFIG_NETWORK_LAYER_BLE
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400561 return devCtrl->CloseBleConnection().AsInteger();
Song Guo87142e02021-04-21 09:00:00 +0800562#else
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400563 return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE.AsInteger();
Song Guo87142e02021-04-21 09:00:00 +0800564#endif
565}
566
Song Guo9ab3c902021-04-09 06:08:35 +0800567uint64_t pychip_GetCommandSenderHandle(chip::Controller::Device * device)
568{
Song Guo8d7486f2021-05-17 23:11:39 +0800569 return 0;
Song Guo9ab3c902021-04-09 06:08:35 +0800570}
571
Andrei Litvinb8287fe2021-02-04 15:23:05 -0500572void pychip_Stack_SetLogFunct(LogMessageFunct logFunct)
yunhanw-google90ea3142020-10-01 13:53:26 -0700573{
Andrei Litvin0a91b1b2021-02-08 09:31:24 -0500574 // TODO: determine if log redirection is supposed to be functioning in CHIP
575 //
576 // Background: original log baseline supported 'redirect logs to this
577 // function' however CHIP does not currently provide this.
578 //
579 // Ideally log redirection should work so that python code can do things
580 // like using the log module.
yunhanw-google90ea3142020-10-01 13:53:26 -0700581}
Song GUOed3b2332021-07-21 02:12:40 +0800582
Kevin Schoedel57874d42021-07-20 21:10:00 -0400583ChipError::StorageType pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext)
Song GUOed3b2332021-07-21 02:12:40 +0800584{
585 if (callback == nullptr || pythonContext == nullptr)
586 {
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400587 return CHIP_ERROR_INVALID_ARGUMENT.AsInteger();
Song GUOed3b2332021-07-21 02:12:40 +0800588 }
Song GUOed3b2332021-07-21 02:12:40 +0800589 PlatformMgr().ScheduleWork(callback, reinterpret_cast<intptr_t>(pythonContext));
Kevin Schoedel0fe17ec2021-08-05 08:52:07 -0400590 return CHIP_NO_ERROR.AsInteger();
Song GUOed3b2332021-07-21 02:12:40 +0800591}
Song GUO75f38952021-10-13 04:13:10 +0800592
593chip::ChipError::StorageType pychip_InteractionModel_ShutdownSubscription(uint64_t subscriptionId)
594{
595 return chip::app::InteractionModelEngine::GetInstance()->ShutdownSubscription(subscriptionId).AsInteger();
596}