Skip to content

Commit

Permalink
[Python] Fix BLE init sequence in Python REPL
Browse files Browse the repository at this point in the history
  • Loading branch information
erjiaqing committed Jul 28, 2022
1 parent fadef3f commit bfaa390
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 27 deletions.
11 changes: 2 additions & 9 deletions src/controller/python/ChipDeviceController-ScriptBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ chip::NodeId kDefaultLocalDeviceId = chip::kTestControllerNodeId;
chip::NodeId kRemoteDeviceId = chip::kTestDeviceNodeId;

extern "C" {
ChipError::StorageType pychip_DeviceController_StackInit(uint32_t bluetoothAdapterId);
ChipError::StorageType pychip_DeviceController_StackInit();
ChipError::StorageType pychip_DeviceController_StackShutdown();

ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl,
Expand Down Expand Up @@ -222,17 +222,10 @@ chip::Controller::Python::StorageAdapter * pychip_Storage_GetStorageAdapter()
return sStorageAdapter;
}

ChipError::StorageType pychip_DeviceController_StackInit(uint32_t bluetoothAdapterId)
ChipError::StorageType pychip_DeviceController_StackInit()
{
VerifyOrDie(sStorageAdapter != nullptr);

#if CHIP_DEVICE_LAYER_TARGET_LINUX && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
// By default, Linux device is configured as a BLE peripheral while the controller needs a BLE central.
CHIP_ERROR err =
chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(/* BLE adapter ID */ bluetoothAdapterId, /* BLE central */ true);
VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
#endif

FactoryInitParams factoryParams;
factoryParams.fabricIndependentStorage = sStorageAdapter;

Expand Down
3 changes: 3 additions & 0 deletions src/controller/python/chip/ChipReplStartup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import argparse
import builtins
import chip.FabricAdmin
import chip.native
from chip.utils import CommissioningBuildingBlocks
import atexit

Expand Down Expand Up @@ -140,6 +141,8 @@ def mattersetdebug(enableDebugMode: bool = True):
"-d", "--debug", help="Set default logging level to debug.", action="store_true")
args = parser.parse_args()

chip.native.Init()

ReplInit(args.debug)
chipStack = ChipStack(persistentStoragePath=args.storagepath)
fabricAdmins = LoadFabricAdmins()
Expand Down
7 changes: 2 additions & 5 deletions src/controller/python/chip/ChipStack.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,8 @@ def HandleChipThreadRun(callback):
#
self._persistentStorage = PersistentStorage(persistentStoragePath)

if (bluetoothAdapter is None):
bluetoothAdapter = 0

# Initialize the chip stack.
res = self._ChipStackLib.pychip_DeviceController_StackInit(bluetoothAdapter)
res = self._ChipStackLib.pychip_DeviceController_StackInit()
if res != 0:
raise self.ErrorToException(res)

Expand Down Expand Up @@ -440,7 +437,7 @@ def _loadLib(self):
self._ChipStackLib = chip.native.GetLibraryHandle()
self._chipDLLPath = chip.native.FindNativeLibraryPath()

self._ChipStackLib.pychip_DeviceController_StackInit.argtypes = [c_uint32]
self._ChipStackLib.pychip_DeviceController_StackInit.argtypes = []
self._ChipStackLib.pychip_DeviceController_StackInit.restype = c_uint32
self._ChipStackLib.pychip_DeviceController_StackShutdown.argtypes = []
self._ChipStackLib.pychip_DeviceController_StackShutdown.restype = c_uint32
Expand Down
25 changes: 20 additions & 5 deletions src/controller/python/chip/native/CommonStackInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,29 @@
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceLayer.h>

static_assert(std::is_same<uint32_t, chip::ChipError::StorageType>::value, "python assumes CHIP_ERROR maps to c_uint32");
using namespace chip;

static_assert(std::is_same<uint32_t, ChipError::StorageType>::value, "python assumes CHIP_ERROR maps to c_uint32");

extern "C" {

chip::ChipError::StorageType pychip_CommonStackInit()
struct __attribute__((packed)) PyCommonStackInitParams
{
uint32_t mBluetoothAdapterId;
};

ChipError::StorageType pychip_CommonStackInit(const PyCommonStackInitParams * aParams)
{
ReturnErrorOnFailure(chip::Platform::MemoryInit().AsInteger());
ReturnErrorOnFailure(chip::DeviceLayer::PlatformMgr().InitChipStack().AsInteger());
ReturnErrorOnFailure(Platform::MemoryInit().AsInteger());

#if CHIP_DEVICE_LAYER_TARGET_LINUX && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
// By default, Linux device is configured as a BLE peripheral while the controller needs a BLE central.
ReturnErrorOnFailure(
DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(aParams->mBluetoothAdapterId, /* BLE central */ true).AsInteger());
#endif

ReturnErrorOnFailure(DeviceLayer::PlatformMgr().InitChipStack().AsInteger());

return CHIP_NO_ERROR.AsInteger();
}

Expand All @@ -55,7 +70,7 @@ void pychip_CommonStackShutdown()
// 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.
//
chip::Platform::MemoryShutdown();
Platform::MemoryShutdown();
#endif
}
};
28 changes: 20 additions & 8 deletions src/controller/python/chip/native/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import glob
import os
import platform
import construct

NATIVE_LIBRARY_BASE_NAME = "_ChipDeviceCtrl.so"

Expand Down Expand Up @@ -69,19 +70,30 @@ def Set(self, methodName: str, resultType, argumentTypes: list):
_nativeLibraryHandle: ctypes.CDLL = None


def GetLibraryHandle() -> ctypes.CDLL:
def _GetLibraryHandle(shouldInit: bool) -> ctypes.CDLL:
"""Get a memoized handle to the chip native code dll."""

global _nativeLibraryHandle
if _nativeLibraryHandle is None:
if shouldInit:
raise Exception("Common stack has not been initialized!")
_nativeLibraryHandle = ctypes.CDLL(FindNativeLibraryPath())
setter = NativeLibraryHandleMethodArguments(_nativeLibraryHandle)
setter.Set("pychip_CommonStackInit", ctypes.c_uint32, [])

#
# 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()
setter.Set("pychip_CommonStackInit", ctypes.c_uint32, [ctypes.c_char_p])

return _nativeLibraryHandle


def Init(bluetoothAdapter: int = None):
CommonStackParams = construct.Struct(
"BluetoothAdapterId" / construct.Int32ul,
)
params = CommonStackParams.parse(b'\x00' * CommonStackParams.sizeof())
params.BluetoothAdapterId = bluetoothAdapter if bluetoothAdapter is not None else 0
params = CommonStackParams.build(params)

_GetLibraryHandle(False).pychip_CommonStackInit(ctypes.c_char_p(params))


def GetLibraryHandle():
return _GetLibraryHandle(True)
3 changes: 3 additions & 0 deletions src/controller/python/test/test_scripts/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import chip.clusters.Attribute as Attribute
from chip.utils import CommissioningBuildingBlocks
from chip.ChipStack import *
import chip.native
import chip.FabricAdmin
import copy
import secrets
Expand Down Expand Up @@ -170,6 +171,8 @@ def assertValueEqual(self, expected):

class BaseTestHelper:
def __init__(self, nodeid: int, paaTrustStorePath: str, testCommissioner: bool = False):
chip.native.Init()

self.chipStack = ChipStack('/tmp/repl_storage.json')
self.fabricAdmin = chip.FabricAdmin.FabricAdmin(vendorId=0XFFF1,
fabricId=1, fabricIndex=1)
Expand Down

0 comments on commit bfaa390

Please sign in to comment.