3 * Copyright (c) 2020-2021 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 * Provides an implementation of the BLEManager singleton object
21 * for the Linux platforms.
26 #include <ble/BleLayer.h>
27 #include <platform/internal/BLEManager.h>
29 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
31 #include "bluez/ChipDeviceScanner.h"
32 #include "bluez/Types.h"
35 namespace DeviceLayer {
38 void HandleIncomingBleConnection(Ble::BLEEndPoint * bleEP);
49 uint8_t mPairingStatus;
52 const char * mpAdvertisingUUID;
55 enum class BleScanState : uint8_t
58 kScanForDiscriminator,
65 // If an active scan for connection is being performed
66 BleScanState mBleScanState = BleScanState::kNotScanning;
68 // If scanning by discriminator, what are we scanning for
69 uint16_t mDiscriminator = 0;
71 // If scanning by address, what address are we searching for
74 // Optional argument to be passed to callback functions provided by the BLE scan/connect requestor
75 void * mAppState = nullptr;
79 * Concrete implementation of the BLEManagerImpl singleton object for the Linux platforms.
81 class BLEManagerImpl final : public BLEManager,
82 private Ble::BleLayer,
83 private Ble::BlePlatformDelegate,
84 private Ble::BleApplicationDelegate,
85 private Ble::BleConnectionDelegate,
86 private ChipDeviceScannerDelegate
88 // Allow the BLEManager interface class to delegate method calls to
89 // the implementation methods provided by this class.
93 CHIP_ERROR ConfigureBle(uint32_t aAdapterId, bool aIsCentral);
96 static void HandleNewConnection(BLE_CONNECTION_OBJECT conId);
97 static void HandleConnectFailed(CHIP_ERROR error);
98 static void HandleWriteComplete(BLE_CONNECTION_OBJECT conId);
99 static void HandleSubscribeOpComplete(BLE_CONNECTION_OBJECT conId, bool subscribed);
100 static void HandleTXCharChanged(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len);
101 static void HandleRXCharWrite(BLE_CONNECTION_OBJECT user_data, const uint8_t * value, size_t len);
102 static void CHIPoBluez_ConnectionClosed(BLE_CONNECTION_OBJECT user_data);
103 static void HandleTXCharCCCDWrite(BLE_CONNECTION_OBJECT user_data);
104 static void HandleTXComplete(BLE_CONNECTION_OBJECT user_data);
106 static void NotifyBLEPeripheralRegisterAppComplete(bool aIsSuccess, void * apAppstate);
107 static void NotifyBLEPeripheralAdvConfiguredComplete(bool aIsSuccess, void * apAppstate);
108 static void NotifyBLEPeripheralAdvStartComplete(bool aIsSuccess, void * apAppstate);
109 static void NotifyBLEPeripheralAdvStopComplete(bool aIsSuccess, void * apAppstate);
112 // ===== Members that implement the BLEManager internal interface.
115 CHIPoBLEServiceMode _GetCHIPoBLEServiceMode();
116 CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val);
117 bool _IsAdvertisingEnabled();
118 CHIP_ERROR _SetAdvertisingEnabled(bool val);
119 bool _IsAdvertising();
120 CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode);
121 CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize);
122 CHIP_ERROR _SetDeviceName(const char * deviceName);
123 uint16_t _NumConnections();
125 void _OnPlatformEvent(const ChipDeviceEvent * event);
126 void HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * event);
127 BleLayer * _GetBleLayer();
129 // ===== Members that implement virtual methods on BlePlatformDelegate.
131 bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
132 const Ble::ChipBleUUID * charId) override;
133 bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
134 const Ble::ChipBleUUID * charId) override;
135 bool CloseConnection(BLE_CONNECTION_OBJECT conId) override;
136 uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override;
137 bool SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
138 System::PacketBufferHandle pBuf) override;
139 bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
140 System::PacketBufferHandle pBuf) override;
141 bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
142 System::PacketBufferHandle pBuf) override;
143 bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const Ble::ChipBleUUID * svcId,
144 const Ble::ChipBleUUID * charId) override;
146 // ===== Members that implement virtual methods on BleApplicationDelegate.
148 void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override;
150 // ===== Members that implement virtual methods on BleConnectionDelegate.
152 void NewConnection(BleLayer * bleLayer, void * appState, uint16_t connDiscriminator) override;
153 BLE_ERROR CancelConnection() override;
155 // ===== Members that implement virtual methods on ChipDeviceScannerDelegate
156 void OnDeviceScanned(BluezDevice1 * device, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
157 void OnScanComplete() override;
159 // ===== Members for internal use by the following friends.
161 friend BLEManager & BLEMgr();
162 friend BLEManagerImpl & BLEMgrImpl();
164 static BLEManagerImpl sInstance;
166 // ===== Private members reserved for use by this class only.
167 enum class Flags : uint16_t
169 kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
170 kBluezBLELayerInitialized = 0x0002, /**< The Bluez layer has been initialized. */
171 kAppRegistered = 0x0004, /**< The CHIPoBLE application has been registered with the Bluez layer. */
172 kAdvertisingConfigured = 0x0008, /**< CHIPoBLE advertising has been configured in the Bluez layer. */
173 kAdvertising = 0x0010, /**< The system is currently CHIPoBLE advertising. */
174 kControlOpInProgress = 0x0020, /**< An async control operation has been issued to the ESP BLE layer. */
175 kAdvertisingEnabled = 0x0040, /**< The application has enabled CHIPoBLE advertising. */
176 kFastAdvertisingEnabled = 0x0080, /**< The application has enabled fast advertising. */
177 kUseCustomDeviceName = 0x0100, /**< The application has configured a custom BLE device name. */
178 kAdvertisingRefreshNeeded = 0x0200, /**< The advertising configuration/state in BLE layer needs to be updated. */
183 kMaxConnections = 1, // TODO: right max connection
184 kMaxDeviceNameLength = 20, // TODO: right-size this
185 kMaxAdvertismentDataSetSize = 31 // TODO: verify this
188 CHIP_ERROR StartBLEAdvertising();
189 CHIP_ERROR StopBLEAdvertising();
191 void DriveBLEState();
192 static void DriveBLEState(intptr_t arg);
194 void InitiateScan(BleScanState scanType);
195 static void InitiateScan(intptr_t arg);
196 void CleanScanConfig();
198 CHIPoBLEServiceMode mServiceMode;
199 BLEAdvConfig mBLEAdvConfig;
200 BLEScanConfig mBLEScanConfig;
201 BitFlags<Flags> mFlags;
202 char mDeviceName[kMaxDeviceNameLength + 1];
203 bool mIsCentral = false;
204 BluezEndpoint * mpEndpoint = nullptr;
205 std::unique_ptr<ChipDeviceScanner> mDeviceScanner;
209 * Returns a reference to the public interface of the BLEManager singleton object.
211 * Internal components should use this to access features of the BLEManager object
212 * that are common to all platforms.
214 inline BLEManager & BLEMgr()
216 return BLEManagerImpl::sInstance;
220 * Returns the platform-specific implementation of the BLEManager singleton object.
222 * Internal components can use this to gain access to features of the BLEManager
223 * that are specific to the Linux platforms.
225 inline BLEManagerImpl & BLEMgrImpl()
227 return BLEManagerImpl::sInstance;
230 inline Ble::BleLayer * BLEManagerImpl::_GetBleLayer()
235 inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode()
240 inline bool BLEManagerImpl::_IsAdvertisingEnabled()
242 return mFlags.Has(Flags::kAdvertisingEnabled);
245 inline bool BLEManagerImpl::_IsAdvertising()
247 return mFlags.Has(Flags::kAdvertising);
250 } // namespace Internal
251 } // namespace DeviceLayer
254 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE