diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index d9cc0dd4fd3d6a..63332c5fe59071 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -44,7 +44,7 @@ shared_library("ChipDeviceCtrl") { "chip/setup_payload/Parser.cpp", ] - sources += [ "CommonStackInit.cpp" ] + sources += [ "chip/native/CommonStackInit.cpp" ] if (chip_controller) { sources += [ diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index 2d54e6fcf7cd09..6fc01943177c7d 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -52,7 +52,6 @@ #include #include -#include #include #include @@ -223,8 +222,6 @@ chip::Controller::Python::StorageAdapter * pychip_Storage_GetStorageAdapter() ChipError::StorageType pychip_DeviceController_StackInit(uint32_t bluetoothAdapterId) { - ReturnErrorOnFailure(chip::Controller::Python::CommonStackInit().AsInteger()); - VerifyOrDie(sStorageAdapter != nullptr); #if CHIP_DEVICE_LAYER_TARGET_LINUX && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE @@ -247,7 +244,7 @@ ChipError::StorageType pychip_DeviceController_StackInit(uint32_t bluetoothAdapt factoryParams.enableServerInteractions = true; // Hack needed due to the fact that DnsSd server uses the CommissionableDataProvider even - // when never starting operational advertising. This will not be used but prevents + // when never starting commissionable advertising. This will not be used but prevents // null pointer dereferences. static chip::DeviceLayer::TestOnlyCommissionableDataProvider TestOnlyCommissionableDataProvider; chip::DeviceLayer::SetCommissionableDataProvider(&TestOnlyCommissionableDataProvider); @@ -291,8 +288,6 @@ ChipError::StorageType pychip_DeviceController_StackShutdown() DeviceControllerFactory::GetInstance().Shutdown(); - chip::Controller::Python::CommonStackShutdown(); - return CHIP_NO_ERROR.AsInteger(); } diff --git a/src/controller/python/CommonStackInit.h b/src/controller/python/CommonStackInit.h deleted file mode 100644 index a28f4163ee5e0f..00000000000000 --- a/src/controller/python/CommonStackInit.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright (c) 2020-2022 Project CHIP Authors - * Copyright (c) 2019-2020 Google LLC. - * Copyright (c) 2013-2018 Nest Labs, Inc. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Implementation of the native methods expected by the Python - * version of Chip Device Manager. - * - */ -#include - -namespace chip { -namespace Controller { -namespace Python { - -// -// This encapsulates stack initialization logic that is common to both -// controller and server initialization sequences. -// -CHIP_ERROR CommonStackInit(); - -// -// This encapsulates stack shutdown logic that is common to both -// controller and server shutdown sequences. -// -void CommonStackShutdown(); - -} // namespace Python -} // namespace Controller -} // namespace chip diff --git a/src/controller/python/chip/ChipStack.py b/src/controller/python/chip/ChipStack.py index f49f28d85bfe4e..ef1cd597d9ef9e 100644 --- a/src/controller/python/chip/ChipStack.py +++ b/src/controller/python/chip/ChipStack.py @@ -46,6 +46,8 @@ from .clusters import Objects as GeneratedObjects from .clusters.CHIPClusters import * +import chip.native + __all__ = [ "DeviceStatusStruct", "ChipStackException", @@ -182,7 +184,10 @@ def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, bl self._activeLogFunct = None self.addModulePrefixToLogMessage = True + # # Locate and load the chip shared library. + # This also implictly does a minimal stack initialization (i.e call MemoryInit). + # self._loadLib() # Arrange to log output from the chip library to a python logger object with the @@ -317,6 +322,12 @@ def Shutdown(self): # to avoid accessing builtins.chipStack after destruction. self._persistentStorage = None self.Call(lambda: self._ChipStackLib.pychip_DeviceController_StackShutdown()) + + # + # Stack init happens in native, but shutdown happens here unfortunately. + # #20437 tracks consolidating these. + # + self._ChipStackLib.pychip_CommonStackShutdown() self.networkLock = None self.completeEvent = None self._ChipStackLib = None @@ -404,42 +415,8 @@ def ErrorToException(self, err, devStatusPtr=None): ) def LocateChipDLL(self): - if self._chipDLLPath: - return self._chipDLLPath - - scriptDir = os.path.dirname(os.path.abspath(__file__)) - - # When properly installed in the chip package, the Chip Device Manager DLL will - # be located in the package root directory, along side the package's - # modules. - dmDLLPath = os.path.join(scriptDir, ChipStackDLLBaseName) - if os.path.exists(dmDLLPath): - self._chipDLLPath = dmDLLPath - return self._chipDLLPath - - # For the convenience of developers, search the list of parent paths relative to the - # running script looking for an CHIP build directory containing the Chip Device - # Manager DLL. This makes it possible to import and use the ChipDeviceMgr module - # directly from a built copy of the CHIP source tree. - buildMachineGlob = "%s-*-%s*" % (platform.machine(), - platform.system().lower()) - relDMDLLPathGlob = os.path.join( - "build", - buildMachineGlob, - "src/controller/python/.libs", - ChipStackDLLBaseName, - ) - for dir in self._AllDirsToRoot(scriptDir): - dmDLLPathGlob = os.path.join(dir, relDMDLLPathGlob) - for dmDLLPath in glob.glob(dmDLLPathGlob): - if os.path.exists(dmDLLPath): - self._chipDLLPath = dmDLLPath - return self._chipDLLPath - - raise Exception( - "Unable to locate Chip Device Manager DLL (%s); expected location: %s" - % (ChipStackDLLBaseName, scriptDir) - ) + self._loadLib() + return self._chipDLLPath # ----- Private Members ----- def _AllDirsToRoot(self, dir): @@ -453,7 +430,9 @@ def _AllDirsToRoot(self, dir): def _loadLib(self): if self._ChipStackLib is None: - self._ChipStackLib = CDLL(self.LocateChipDLL()) + self._ChipStackLib = chip.native.GetLibraryHandle() + self._chipDLLPath = chip.native.FindNativeLibraryPath() + self._ChipStackLib.pychip_DeviceController_StackInit.argtypes = [c_uint32] self._ChipStackLib.pychip_DeviceController_StackInit.restype = c_uint32 self._ChipStackLib.pychip_DeviceController_StackShutdown.argtypes = [] diff --git a/src/controller/python/CommonStackInit.cpp b/src/controller/python/chip/native/CommonStackInit.cpp similarity index 85% rename from src/controller/python/CommonStackInit.cpp rename to src/controller/python/chip/native/CommonStackInit.cpp index 7bfdb860e04531..a6a9b3e455899e 100644 --- a/src/controller/python/CommonStackInit.cpp +++ b/src/controller/python/chip/native/CommonStackInit.cpp @@ -25,8 +25,6 @@ * */ -#include - #include #include @@ -39,21 +37,19 @@ #include #include -namespace chip { -namespace Controller { -namespace Python { +static_assert(std::is_same::value, "python assumes CHIP_ERROR maps to c_uint32"); + +extern "C" { -CHIP_ERROR CommonStackInit() +CHIP_ERROR pychip_CommonStackInit() { ReturnErrorOnFailure(chip::Platform::MemoryInit()); ReturnErrorOnFailure(chip::DeviceLayer::PlatformMgr().InitChipStack()); return CHIP_NO_ERROR; } -void CommonStackShutdown() +void pychip_CommonStackShutdown() { - chip::DeviceLayer::PlatformMgr().Shutdown(); - #if 0 // // We cannot actually call this because the destructor for the MdnsContexts singleton on Darwin only gets called // on termination of the program, and that unfortunately makes a bunch of Platform::MemoryFree calls. @@ -61,7 +57,4 @@ void CommonStackShutdown() chip::Platform::MemoryShutdown(); #endif } - -} // namespace Python -} // namespace Controller -} // namespace chip +}; diff --git a/src/controller/python/chip/native/__init__.py b/src/controller/python/chip/native/__init__.py index b34bb0adb1f4a0..e147f684f605e3 100644 --- a/src/controller/python/chip/native/__init__.py +++ b/src/controller/python/chip/native/__init__.py @@ -76,5 +76,12 @@ def GetLibraryHandle() -> ctypes.CDLL: if _nativeLibraryHandle is None: _nativeLibraryHandle = ctypes.CDLL(FindNativeLibraryPath()) setter = NativeLibraryHandleMethodArguments(_nativeLibraryHandle) + setter.Set("pychip_CommonStackInit", None, []) + + # + # We've a split initialization model with some init happening here and some other + # bits of init happening in ChipStack. #20437 tracks consolidating those. + # + _nativeLibraryHandle.pychip_CommonStackInit() return _nativeLibraryHandle