Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / platform / Linux / BLEManagerImpl.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *
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
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 /**
19  *    @file
20  *          Provides an implementation of the BLEManager singleton object
21  *          for the Linux platforms.
22  */
23
24 #pragma once
25
26 #include <ble/BleLayer.h>
27 #include <platform/internal/BLEManager.h>
28
29 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
30
31 #include "bluez/ChipDeviceScanner.h"
32 #include "bluez/Types.h"
33
34 namespace chip {
35 namespace DeviceLayer {
36 namespace Internal {
37
38 void HandleIncomingBleConnection(Ble::BLEEndPoint * bleEP);
39
40 struct BLEAdvConfig
41 {
42     char * mpBleName;
43     uint32_t mAdapterId;
44     uint8_t mMajor;
45     uint8_t mMinor;
46     uint16_t mVendorId;
47     uint16_t mProductId;
48     uint64_t mDeviceId;
49     uint8_t mPairingStatus;
50     ChipAdvType mType;
51     uint16_t mDuration;
52     const char * mpAdvertisingUUID;
53 };
54
55 enum class BleScanState
56 {
57     kNotScanning,
58     kScanForDiscriminator,
59     kScanForAddress,
60 };
61
62 struct BLEScanConfig
63 {
64     // If a active scan for connection is being performed
65     BleScanState bleScanState = BleScanState::kNotScanning;
66
67     // If scanning by discriminator, what are we scanning for
68     uint16_t mDiscriminator = 0;
69
70     // If scanning by address, what address are we searching for
71     std::string mAddress;
72
73     // Optional argument to be passed to callback functions provided by the BLE scan/connect requestor
74     void * mAppState = nullptr;
75 };
76
77 /**
78  * Concrete implementation of the BLEManagerImpl singleton object for the Linux platforms.
79  */
80 class BLEManagerImpl final : public BLEManager,
81                              private Ble::BleLayer,
82                              private Ble::BlePlatformDelegate,
83                              private Ble::BleApplicationDelegate,
84                              private Ble::BleConnectionDelegate,
85                              private ChipDeviceScannerDelegate
86 {
87     // Allow the BLEManager interface class to delegate method calls to
88     // the implementation methods provided by this class.
89     friend BLEManager;
90
91 public:
92     CHIP_ERROR ConfigureBle(uint32_t aAdapterId, bool aIsCentral);
93
94     // Driven by BlueZ IO
95     static void HandleNewConnection(BLE_CONNECTION_OBJECT conId);
96     static void HandleWriteComplete(BLE_CONNECTION_OBJECT conId);
97     static void HandleSubscribeOpComplete(BLE_CONNECTION_OBJECT conId, bool subscribed);
98     static void HandleTXCharChanged(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len);
99     static void HandleRXCharWrite(BLE_CONNECTION_OBJECT user_data, const uint8_t * value, size_t len);
100     static void CHIPoBluez_ConnectionClosed(BLE_CONNECTION_OBJECT user_data);
101     static void HandleTXCharCCCDWrite(BLE_CONNECTION_OBJECT user_data);
102     static void HandleTXComplete(BLE_CONNECTION_OBJECT user_data);
103     static bool WoBLEz_TimerCb(BLE_CONNECTION_OBJECT user_data);
104
105     static void NotifyBLEPeripheralRegisterAppComplete(bool aIsSuccess, void * apAppstate);
106     static void NotifyBLEPeripheralAdvConfiguredComplete(bool aIsSuccess, void * apAppstate);
107     static void NotifyBLEPeripheralAdvStartComplete(bool aIsSuccess, void * apAppstate);
108     static void NotifyBLEPeripheralAdvStopComplete(bool aIsSuccess, void * apAppstate);
109
110 private:
111     // ===== Members that implement the BLEManager internal interface.
112
113     CHIP_ERROR _Init();
114     CHIPoBLEServiceMode _GetCHIPoBLEServiceMode();
115     CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val);
116     bool _IsAdvertisingEnabled();
117     CHIP_ERROR _SetAdvertisingEnabled(bool val);
118     bool _IsFastAdvertisingEnabled();
119     CHIP_ERROR _SetFastAdvertisingEnabled(bool val);
120     bool _IsAdvertising();
121     CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize);
122     CHIP_ERROR _SetDeviceName(const char * deviceName);
123     uint16_t _NumConnections();
124
125     void _OnPlatformEvent(const ChipDeviceEvent * event);
126     void HandlePlatformSpecificBLEEvent(const ChipDeviceEvent * event);
127     BleLayer * _GetBleLayer();
128
129     // ===== Members that implement virtual methods on BlePlatformDelegate.
130
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;
145
146     // ===== Members that implement virtual methods on BleApplicationDelegate.
147
148     void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override;
149
150     // ===== Members that implement virtual methods on BleConnectionDelegate.
151
152     void NewConnection(BleLayer * bleLayer, void * appState, uint16_t connDiscriminator) override;
153
154     // ===== Members that implement virtual methods on ChipDeviceScannerDelegate
155     void OnDeviceScanned(BluezDevice1 * device, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
156     void OnScanComplete() override;
157
158     // ===== Members for internal use by the following friends.
159
160     friend BLEManager & BLEMgr();
161     friend BLEManagerImpl & BLEMgrImpl();
162
163     static BLEManagerImpl sInstance;
164
165     // ===== Private members reserved for use by this class only.
166     enum class Flags : uint16_t
167     {
168         kAsyncInitCompleted       = 0x0001, /**< One-time asynchronous initialization actions have been performed. */
169         kBluezBLELayerInitialized = 0x0002, /**< The Bluez layer has been initialized. */
170         kAppRegistered            = 0x0004, /**< The CHIPoBLE application has been registered with the Bluez layer. */
171         kAdvertisingConfigured    = 0x0008, /**< CHIPoBLE advertising has been configured in the Bluez layer. */
172         kAdvertising              = 0x0010, /**< The system is currently CHIPoBLE advertising. */
173         kControlOpInProgress      = 0x0020, /**< An async control operation has been issued to the ESP BLE layer. */
174         kAdvertisingEnabled       = 0x0040, /**< The application has enabled CHIPoBLE advertising. */
175         kFastAdvertisingEnabled   = 0x0080, /**< The application has enabled fast advertising. */
176         kUseCustomDeviceName      = 0x0100, /**< The application has configured a custom BLE device name. */
177         kAdvertisingRefreshNeeded = 0x0200, /**< The advertising configuration/state in BLE layer needs to be updated. */
178     };
179
180     enum
181     {
182         kMaxConnections             = 1,  // TODO: right max connection
183         kMaxDeviceNameLength        = 20, // TODO: right-size this
184         kMaxAdvertismentDataSetSize = 31  // TODO: verify this
185     };
186
187     CHIP_ERROR StartBLEAdvertising();
188     CHIP_ERROR StopBLEAdvertising();
189
190     void DriveBLEState();
191     static void DriveBLEState(intptr_t arg);
192
193     void InitiateScan(BleScanState scanType);
194     static void InitiateScan(intptr_t arg);
195
196     CHIPoBLEServiceMode mServiceMode;
197     BLEAdvConfig mBLEAdvConfig;
198     BLEScanConfig mBLEScanConfig;
199     BitFlags<Flags> mFlags;
200     char mDeviceName[kMaxDeviceNameLength + 1];
201     bool mIsCentral            = false;
202     BluezEndpoint * mpEndpoint = nullptr;
203     std::unique_ptr<ChipDeviceScanner> mDeviceScanner;
204 };
205
206 /**
207  * Returns a reference to the public interface of the BLEManager singleton object.
208  *
209  * Internal components should use this to access features of the BLEManager object
210  * that are common to all platforms.
211  */
212 inline BLEManager & BLEMgr()
213 {
214     return BLEManagerImpl::sInstance;
215 }
216
217 /**
218  * Returns the platform-specific implementation of the BLEManager singleton object.
219  *
220  * Internal components can use this to gain access to features of the BLEManager
221  * that are specific to the Linux platforms.
222  */
223 inline BLEManagerImpl & BLEMgrImpl()
224 {
225     return BLEManagerImpl::sInstance;
226 }
227
228 inline Ble::BleLayer * BLEManagerImpl::_GetBleLayer()
229 {
230     return this;
231 }
232
233 inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode()
234 {
235     return mServiceMode;
236 }
237
238 inline bool BLEManagerImpl::_IsAdvertisingEnabled()
239 {
240     return mFlags.Has(Flags::kAdvertisingEnabled);
241 }
242
243 inline bool BLEManagerImpl::_IsFastAdvertisingEnabled()
244 {
245     return mFlags.Has(Flags::kFastAdvertisingEnabled);
246 }
247
248 inline bool BLEManagerImpl::_IsAdvertising()
249 {
250     return mFlags.Has(Flags::kAdvertising);
251 }
252
253 } // namespace Internal
254 } // namespace DeviceLayer
255 } // namespace chip
256
257 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE