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 Zephyr platforms.
26 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
28 #include <bluetooth/bluetooth.h>
29 #include <bluetooth/conn.h>
30 #include <bluetooth/gatt.h>
32 #include <support/logging/CHIPLogging.h>
34 #include <type_traits>
37 namespace DeviceLayer {
40 using namespace chip::Ble;
43 * Concrete implementation of the BLEManager singleton object for the Zephyr platforms.
45 class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate
47 // Allow the BLEManager interface class to delegate method calls to
48 // the implementation methods provided by this class.
52 // As a result of https://github.com/zephyrproject-rtos/zephyr/issues/29357, BLE indication
53 // callback parameter type has changed in recent Zephyr revisions. Select the compatible type
54 // below to support both versions for now.
55 using IndicationAttrType =
56 std::conditional_t<std::is_same<bt_gatt_indicate_func_t, void (*)(bt_conn *, bt_gatt_indicate_params *, uint8_t)>::value,
57 bt_gatt_indicate_params *, const bt_gatt_attr *>;
59 // ===== Members that implement the BLEManager internal interface.
61 CHIP_ERROR _Init(void);
62 CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void);
63 CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val);
64 bool _IsAdvertisingEnabled(void);
65 CHIP_ERROR _SetAdvertisingEnabled(bool val);
66 bool _IsFastAdvertisingEnabled(void);
67 CHIP_ERROR _SetFastAdvertisingEnabled(bool val);
68 bool _IsAdvertising(void);
69 CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize);
70 CHIP_ERROR _SetDeviceName(const char * deviceName);
71 uint16_t _NumConnections(void);
72 void _OnPlatformEvent(const ChipDeviceEvent * event);
73 BleLayer * _GetBleLayer(void);
75 // ===== Members that implement virtual methods on BlePlatformDelegate.
77 bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId);
78 bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId);
79 bool CloseConnection(BLE_CONNECTION_OBJECT conId);
80 uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const;
81 bool SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
82 PacketBufferHandle pBuf);
83 bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
84 PacketBufferHandle pBuf);
85 bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId,
86 PacketBufferHandle pBuf);
87 bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId,
88 const ChipBleUUID * charId);
90 // ===== Members that implement virtual methods on BleApplicationDelegate.
92 void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId);
94 // ===== Private members reserved for use by this class only.
96 enum class Flags : uint8_t
98 kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
99 kAdvertisingEnabled = 0x0002, /**< The application has enabled CHIPoBLE advertising. */
100 kFastAdvertisingEnabled = 0x0004, /**< The application has enabled fast advertising. */
101 kAdvertising = 0x0008, /**< The system is currently CHIPoBLE advertising. */
102 kAdvertisingRefreshNeeded =
103 0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */
108 BitFlags<Flags> mFlags;
110 CHIPoBLEServiceMode mServiceMode;
111 bool mSubscribedConns[CONFIG_BT_MAX_CONN];
112 bt_gatt_indicate_params mIndicateParams[CONFIG_BT_MAX_CONN];
113 bt_conn_cb mConnCallbacks;
115 void DriveBLEState(void);
116 CHIP_ERROR ConfigureAdvertising(void);
117 CHIP_ERROR StartAdvertising(void);
118 CHIP_ERROR StopAdvertising(void);
119 CHIP_ERROR HandleGAPConnect(const ChipDeviceEvent * event);
120 CHIP_ERROR HandleGAPDisconnect(const ChipDeviceEvent * event);
121 CHIP_ERROR HandleRXCharWrite(const ChipDeviceEvent * event);
122 CHIP_ERROR HandleTXCharCCCDWrite(const ChipDeviceEvent * event);
123 CHIP_ERROR HandleTXComplete(const ChipDeviceEvent * event);
124 bool IsSubscribed(bt_conn * conn);
125 bool SetSubscribed(bt_conn * conn);
126 bool UnsetSubscribed(bt_conn * conn);
127 uint32_t GetAdvertisingInterval();
129 static void DriveBLEState(intptr_t arg);
131 // Below callbacks run from the system workqueue context and have a limited stack capacity.
132 static void HandleTXIndicated(bt_conn * conn, IndicationAttrType attr, uint8_t err);
133 static void HandleConnect(bt_conn * conn, uint8_t err);
134 static void HandleDisconnect(bt_conn * conn, uint8_t reason);
135 static void HandleBLEAdvertisementTimeout(System::Layer * layer, void * param, System::Error error);
137 // ===== Members for internal use by the following friends.
139 friend BLEManager & BLEMgr(void);
140 friend BLEManagerImpl & BLEMgrImpl(void);
142 static BLEManagerImpl sInstance;
145 // Below callbacks are public in order to be visible from the global scope.
146 static ssize_t HandleRXWrite(bt_conn * conn, const bt_gatt_attr * attr, const void * buf, uint16_t len, uint16_t offset,
148 static ssize_t HandleTXCCCWrite(bt_conn * conn, const bt_gatt_attr * attr, uint16_t value);
152 * Returns a reference to the public interface of the BLEManager singleton object.
154 * Internal components should use this to access features of the BLEManager object
155 * that are common to all platforms.
157 inline BLEManager & BLEMgr(void)
159 return BLEManagerImpl::sInstance;
163 * Returns the platform-specific implementation of the BLEManager singleton object.
165 * Internal components can use this to gain access to features of the BLEManager
166 * that are specific to the Zephyr platforms.
168 inline BLEManagerImpl & BLEMgrImpl(void)
170 return BLEManagerImpl::sInstance;
173 inline BleLayer * BLEManagerImpl::_GetBleLayer()
178 inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void)
183 inline bool BLEManagerImpl::_IsAdvertisingEnabled(void)
185 return mFlags.Has(Flags::kAdvertisingEnabled);
188 inline bool BLEManagerImpl::_IsFastAdvertisingEnabled(void)
190 return mFlags.Has(Flags::kFastAdvertisingEnabled);
193 inline bool BLEManagerImpl::_IsAdvertising(void)
195 return mFlags.Has(Flags::kAdvertising);
198 } // namespace Internal
199 } // namespace DeviceLayer
202 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE