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