Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / ESP32 / BLEManagerImpl.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    Copyright (c) 2018 Nest Labs, Inc.
5  *    All rights reserved.
6  *
7  *    Licensed under the Apache License, Version 2.0 (the "License");
8  *    you may not use this file except in compliance with the License.
9  *    You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing, software
14  *    distributed under the License is distributed on an "AS IS" BASIS,
15  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *    See the License for the specific language governing permissions and
17  *    limitations under the License.
18  */
19
20 /**
21  *    @file
22  *          Provides an implementation of the BLEManager singleton object
23  *          for the ESP32 platform.
24  */
25
26 #pragma once
27
28 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
29
30 #include "sdkconfig.h"
31
32 #if CONFIG_BT_BLUEDROID_ENABLED
33
34 #include "core/CHIPCallback.h"
35 #include "esp_bt.h"
36 #include "esp_gap_ble_api.h"
37 #include "esp_gatts_api.h"
38 #elif CONFIG_BT_NIMBLE_ENABLED
39
40 /* min max macros in NimBLE can cause build issues with generic min max
41  * functions defined in CHIP.*/
42 #define min
43 #define max
44 #include "host/ble_hs.h"
45 #undef min
46 #undef max
47
48 /* GATT context */
49 struct ble_gatt_char_context
50 {
51     uint16_t conn_handle;
52     uint16_t attr_handle;
53     struct ble_gatt_access_ctxt * ctxt;
54     void * arg;
55 };
56
57 #endif
58
59 namespace chip {
60 namespace DeviceLayer {
61 namespace Internal {
62
63 /**
64  * Concrete implementation of the BLEManager singleton object for the ESP32 platform.
65  */
66 class BLEManagerImpl final : public BLEManager,
67                              private Ble::BleLayer,
68                              private Ble::BlePlatformDelegate,
69                              private Ble::BleApplicationDelegate
70 {
71 public:
72     BLEManagerImpl();
73
74 private:
75     // Allow the BLEManager interface class to delegate method calls to
76     // the implementation methods provided by this class.
77     friend BLEManager;
78
79     // ===== Members that implement the BLEManager internal interface.
80
81     CHIP_ERROR _Init(void);
82     CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void);
83     CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val);
84     bool _IsAdvertisingEnabled(void);
85     CHIP_ERROR _SetAdvertisingEnabled(bool val);
86     bool _IsAdvertising(void);
87     CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode);
88     CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize);
89     CHIP_ERROR _SetDeviceName(const char * deviceName);
90     uint16_t _NumConnections(void);
91     void _OnPlatformEvent(const ChipDeviceEvent * event);
92     ::chip::Ble::BleLayer * _GetBleLayer(void);
93
94     // ===== Members that implement virtual methods on BlePlatformDelegate.
95
96     bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
97                                  const Ble::ChipBleUUID * charId) override;
98     bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId,
99                                    const Ble::ChipBleUUID * charId) override;
100     bool CloseConnection(BLE_CONNECTION_OBJECT conId) override;
101     uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override;
102     bool SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
103                         System::PacketBufferHandle pBuf) override;
104     bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
105                           System::PacketBufferHandle pBuf) override;
106     bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId,
107                          System::PacketBufferHandle pBuf) override;
108     bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const Ble::ChipBleUUID * svcId,
109                           const Ble::ChipBleUUID * charId) override;
110
111     // ===== Members that implement virtual methods on BleApplicationDelegate.
112
113     void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override;
114
115     // ===== Members for internal use by the following friends.
116
117     friend BLEManager & BLEMgr(void);
118     friend BLEManagerImpl & BLEMgrImpl(void);
119
120     static BLEManagerImpl sInstance;
121
122     // ===== Private members reserved for use by this class only.
123
124     enum class Flags : uint16_t
125     {
126         kAsyncInitCompleted       = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
127         kESPBLELayerInitialized   = 0x0002, /**< The ESP BLE layer has been initialized. */
128         kAppRegistered            = 0x0004, /**< The CHIPoBLE application has been registered with the ESP BLE layer. */
129         kAttrsRegistered          = 0x0008, /**< The CHIPoBLE GATT attributes have been registered with the ESP BLE layer. */
130         kGATTServiceStarted       = 0x0010, /**< The CHIPoBLE GATT service has been started. */
131         kAdvertisingConfigured    = 0x0020, /**< CHIPoBLE advertising has been configured in the ESP BLE layer. */
132         kAdvertising              = 0x0040, /**< The system is currently CHIPoBLE advertising. */
133         kControlOpInProgress      = 0x0080, /**< An async control operation has been issued to the ESP BLE layer. */
134         kAdvertisingEnabled       = 0x0100, /**< The application has enabled CHIPoBLE advertising. */
135         kFastAdvertisingEnabled   = 0x0200, /**< The application has enabled fast advertising. */
136         kUseCustomDeviceName      = 0x0400, /**< The application has configured a custom BLE device name. */
137         kAdvertisingRefreshNeeded = 0x0800, /**< The advertising configuration/state in ESP BLE layer needs to be updated. */
138     };
139
140     enum
141     {
142         kMaxConnections      = BLE_LAYER_NUM_BLE_ENDPOINTS,
143         kMaxDeviceNameLength = 16
144     };
145
146 #if CONFIG_BT_NIMBLE_ENABLED
147     uint16_t mSubscribedConIds[kMaxConnections];
148 #endif
149
150     struct CHIPoBLEConState
151     {
152         System::PacketBufferHandle PendingIndBuf;
153         uint16_t ConId;
154         uint16_t MTU : 10;
155         uint16_t Allocated : 1;
156         uint16_t Subscribed : 1;
157         uint16_t Unused : 4;
158
159         void Set(uint16_t conId)
160         {
161             PendingIndBuf = nullptr;
162             ConId         = conId;
163             MTU           = 0;
164             Allocated     = 1;
165             Subscribed    = 0;
166             Unused        = 0;
167         }
168         void Reset()
169         {
170             PendingIndBuf = nullptr;
171             ConId         = BLE_CONNECTION_UNINITIALIZED;
172             MTU           = 0;
173             Allocated     = 0;
174             Subscribed    = 0;
175             Unused        = 0;
176         }
177     };
178
179     CHIPoBLEConState mCons[kMaxConnections];
180     CHIPoBLEServiceMode mServiceMode;
181 #if CONFIG_BT_BLUEDROID_ENABLED
182     esp_gatt_if_t mAppIf;
183 #elif CONFIG_BT_NIMBLE_ENABLED
184     uint16_t mNumGAPCons;
185 #endif
186     uint16_t mServiceAttrHandle;
187     uint16_t mRXCharAttrHandle;
188     uint16_t mTXCharAttrHandle;
189     uint16_t mTXCharCCCDAttrHandle;
190     BitFlags<Flags> mFlags;
191     char mDeviceName[kMaxDeviceNameLength + 1];
192
193     void DriveBLEState(void);
194     CHIP_ERROR InitESPBleLayer(void);
195     CHIP_ERROR ConfigureAdvertisingData(void);
196     CHIP_ERROR StartAdvertising(void);
197
198 #if CONFIG_BT_BLUEDROID_ENABLED
199     void HandleGATTControlEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param);
200     void HandleGATTCommEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param);
201     void HandleRXCharWrite(esp_ble_gatts_cb_param_t * param);
202     void HandleTXCharRead(esp_ble_gatts_cb_param_t * param);
203     void HandleTXCharCCCDRead(esp_ble_gatts_cb_param_t * param);
204     void HandleTXCharCCCDWrite(esp_ble_gatts_cb_param_t * param);
205     void HandleTXCharConfirm(CHIPoBLEConState * conState, esp_ble_gatts_cb_param_t * param);
206     void HandleDisconnect(esp_ble_gatts_cb_param_t * param);
207     CHIPoBLEConState * GetConnectionState(uint16_t conId, bool allocate = false);
208     bool ReleaseConnectionState(uint16_t conId);
209
210     static void HandleGATTEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param);
211     static void HandleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t * param);
212
213 #elif CONFIG_BT_NIMBLE_ENABLED
214     static constexpr uint32_t kAdvertiseTimeout     = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT;
215     static constexpr uint32_t kFastAdvertiseTimeout = CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME;
216     uint64_t mAdvertiseStartTime;
217     chip::Callback::Callback<> mAdvertiseTimerCallback;
218     chip::Callback::Callback<> mFastAdvertiseTimerCallback;
219
220     static void HandleFastAdvertisementTimer(void * context);
221     void HandleFastAdvertisementTimer();
222     static void HandleAdvertisementTimer(void * context);
223     void HandleAdvertisementTimer();
224
225     void HandleRXCharRead(struct ble_gatt_char_context * param);
226     void HandleRXCharWrite(struct ble_gatt_char_context * param);
227     void HandleTXCharWrite(struct ble_gatt_char_context * param);
228     void HandleTXCharRead(struct ble_gatt_char_context * param);
229     void HandleTXCharCCCDRead(void * param);
230     void HandleTXCharCCCDWrite(struct ble_gap_event * gapEvent);
231     CHIP_ERROR HandleTXComplete(struct ble_gap_event * gapEvent);
232     CHIP_ERROR HandleGAPConnect(struct ble_gap_event * gapEvent);
233     CHIP_ERROR HandleGAPDisconnect(struct ble_gap_event * gapEvent);
234     CHIP_ERROR SetSubscribed(uint16_t conId);
235     bool UnsetSubscribed(uint16_t conId);
236     bool IsSubscribed(uint16_t conId);
237
238     static void bleprph_host_task(void * param);
239     static void bleprph_on_sync(void);
240     static void bleprph_on_reset(int);
241     static const struct ble_gatt_svc_def CHIPoBLEGATTAttrs[];
242     static int ble_svr_gap_event(struct ble_gap_event * event, void * arg);
243
244     static int gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt * ctxt, void * arg);
245 #endif
246
247     static void DriveBLEState(intptr_t arg);
248 };
249
250 /**
251  * Returns a reference to the public interface of the BLEManager singleton object.
252  *
253  * Internal components should use this to access features of the BLEManager object
254  * that are common to all platforms.
255  */
256 inline BLEManager & BLEMgr(void)
257 {
258     return BLEManagerImpl::sInstance;
259 }
260
261 /**
262  * Returns the platform-specific implementation of the BLEManager singleton object.
263  *
264  * Internal components can use this to gain access to features of the BLEManager
265  * that are specific to the ESP32 platform.
266  */
267 inline BLEManagerImpl & BLEMgrImpl(void)
268 {
269     return BLEManagerImpl::sInstance;
270 }
271
272 inline ::chip::Ble::BleLayer * BLEManagerImpl::_GetBleLayer()
273 {
274     return this;
275 }
276
277 inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void)
278 {
279     return mServiceMode;
280 }
281
282 inline bool BLEManagerImpl::_IsAdvertisingEnabled(void)
283 {
284     return mFlags.Has(Flags::kAdvertisingEnabled);
285 }
286
287 inline bool BLEManagerImpl::_IsAdvertising(void)
288 {
289     return mFlags.Has(Flags::kAdvertising);
290 }
291
292 } // namespace Internal
293 } // namespace DeviceLayer
294 } // namespace chip
295
296 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE