diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index c7db1e3a4cd035..f9b1cc3c770ef5 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -773,6 +773,9 @@ CHIP_ERROR DeviceCommissioner::EstablishPASEConnection(NodeId remoteDeviceId, Re params.GetPeerAddress().GetTransportType() == Transport::Type::kUndefined) { #if CONFIG_NETWORK_LAYER_BLE +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + ConnectBleTransportToSelf(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE if (!params.HasBleLayer()) { params.SetPeerAddress(Transport::PeerAddress::BLE()); @@ -1327,6 +1330,17 @@ CHIP_ERROR DeviceCommissioner::OnOperationalCredentialsProvisioningCompletion(Co } #if CONFIG_NETWORK_LAYER_BLE +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE +void DeviceCommissioner::ConnectBleTransportToSelf() +{ + Transport::BLEBase & transport = std::get>(mSystemState->TransportMgr()->GetTransport().GetTransports()); + if (!transport.IsBleLayerTransportSetToSelf()) + { + transport.SetBleLayerTransportToSelf(); + } +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + CHIP_ERROR DeviceCommissioner::CloseBleConnection() { // It is fine since we can only commission one device at the same time. diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 6e1716637f0992..0dcc2cb1f1eed1 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -603,6 +603,15 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, CommissioningDelegate::CommissioningReport report = CommissioningDelegate::CommissioningReport()); #if CONFIG_NETWORK_LAYER_BLE +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + /** + * @brief + * Prior to commissioning, the Controller should make sure the BleLayer transport + * is set to the Commissioner transport and not the Server transport. + */ + void ConnectBleTransportToSelf(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + /** * @brief * Once we have finished all commissioning work, the Controller should close the BLE diff --git a/src/controller/SetUpCodePairer.cpp b/src/controller/SetUpCodePairer.cpp index 6817d2181bf801..0892f3957e58a4 100644 --- a/src/controller/SetUpCodePairer.cpp +++ b/src/controller/SetUpCodePairer.cpp @@ -85,6 +85,10 @@ CHIP_ERROR SetUpCodePairer::Connect(SetupPayload & payload) CHIP_ERROR SetUpCodePairer::StartDiscoverOverBle(SetupPayload & payload) { #if CONFIG_NETWORK_LAYER_BLE +#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + mCommissioner->ConnectBleTransportToSelf(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); return mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess, OnDiscoveredDeviceOverBleError); diff --git a/src/transport/raw/BLE.cpp b/src/transport/raw/BLE.cpp index f41a01b07e236a..d1581b4d97db26 100644 --- a/src/transport/raw/BLE.cpp +++ b/src/transport/raw/BLE.cpp @@ -47,6 +47,7 @@ void BLEBase::ClearState() { mBleLayer->CancelBleIncompleteConnection(); mBleLayer->OnChipBleConnectReceived = nullptr; + mBleLayer->mBleTransport = nullptr; mBleLayer = nullptr; } @@ -66,8 +67,16 @@ CHIP_ERROR BLEBase::Init(const BleListenParameters & param) VerifyOrReturnError(mState == State::kNotReady, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(bleLayer != nullptr, CHIP_ERROR_INCORRECT_STATE); - mBleLayer = bleLayer; - mBleLayer->mBleTransport = this; + mBleLayer = bleLayer; + if (mBleLayer->mBleTransport == nullptr || !param.PreserveExistingBleLayerTransport()) + { + mBleLayer->mBleTransport = this; + ChipLogDetail(Inet, "BLEBase::Init - setting/overriding transport"); + } + else + { + ChipLogDetail(Inet, "BLEBase::Init - not overriding transport"); + } mBleLayer->OnChipBleConnectReceived = nullptr; mState = State::kInitialized; diff --git a/src/transport/raw/BLE.h b/src/transport/raw/BLE.h index d54ecc2454d586..548af414b2fffe 100644 --- a/src/transport/raw/BLE.h +++ b/src/transport/raw/BLE.h @@ -48,8 +48,39 @@ class BleListenParameters Ble::BleLayer * GetBleLayer() const { return mLayer; } + /** + * PreserveExistingBleLayerTransport controls whether the BleBase transport + * initialized with these parameters should update the global BleLayer transport + * if it is already set. + * + * This is relevant when there is more than one TransportMgr, + * for example, when a device is both a commissioner (has a CHIPDeviceController) + * and a commissionee (has a Server) since each TransportMgr will have a BleBase + * which can override the global BleLayer transport to point to itself. + * + * The default value is true - don't override the global BleLayer transport if it is + * already set. In other words, the first BleBase to initialize (eg. Server) will be + * the active BleBase transport, and the second BleBase to initialize (eg. CHIPDeviceController) + * will need to call BleBase.SetBleLayerTransportToSelf if it needs to commission using BLE. + * + * Call SetPreserveExistingBleLayerTransport(false) to set the global + * BleLayer transport to the BleBase created with these parameters, even if it is already + * set to another BleBase. + * + * Use the BleBase.IsBleLayerTransportSetToSelf() and BleBase.SetBleLayerTransportToSelf + * methods to toggle between BleBase transports when there is more than one. + */ + bool PreserveExistingBleLayerTransport() const { return mPreserveExistingBleLayerTransport; } + BleListenParameters & SetPreserveExistingBleLayerTransport(bool preserveExistingBleLayerTransport) + { + mPreserveExistingBleLayerTransport = preserveExistingBleLayerTransport; + + return *this; + } + private: Ble::BleLayer * mLayer; + bool mPreserveExistingBleLayerTransport = true; }; /** Implements a transport using BLE. @@ -91,6 +122,20 @@ class DLL_EXPORT BLEBase : public Base, public Ble::BleLayerDelegate CHIP_ERROR SetEndPoint(Ble::BLEEndPoint * endPoint) override; + /** + * Change BLE transport to this + * + * This is relevant when there is more than one TransportMgr, + * for example, when a device is both a commissioner (has a CHIPDeviceController) + * and a commissionee (has a Server) since each TransportMgr will set + * the global BleLayer transport to point to itself. + * + * In this scenario, the device will need the ability to toggle between a + * BleLayer transport for commissioner functionality and one for commissionee functionality. + */ + void SetBleLayerTransportToSelf() { mBleLayer->mBleTransport = this; } + bool IsBleLayerTransportSetToSelf() { return mBleLayer->mBleTransport == this; } + private: void ClearState(); diff --git a/src/transport/raw/Tuple.h b/src/transport/raw/Tuple.h index 3cd3b387909bf5..743b9b9b0e09aa 100644 --- a/src/transport/raw/Tuple.h +++ b/src/transport/raw/Tuple.h @@ -281,6 +281,8 @@ class Tuple : public Base { return std::get(mTransports); } + + std::tuple & GetTransports() { return mTransports; } }; } // namespace Transport