Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / platform / Zephyr / 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 Zephyr platforms.
22  */
23
24 #pragma once
25
26 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
27
28 #include <bluetooth/bluetooth.h>
29 #include <bluetooth/conn.h>
30 #include <bluetooth/gatt.h>
31
32 #include <support/logging/CHIPLogging.h>
33
34 #include <type_traits>
35
36 namespace chip {
37 namespace DeviceLayer {
38 namespace Internal {
39
40 using namespace chip::Ble;
41
42 /**
43  * Concrete implementation of the BLEManager singleton object for the Zephyr platforms.
44  */
45 class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate
46 {
47     // Allow the BLEManager interface class to delegate method calls to
48     // the implementation methods provided by this class.
49     friend BLEManager;
50
51 private:
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 *>;
58
59     // ===== Members that implement the BLEManager internal interface.
60
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);
74
75     // ===== Members that implement virtual methods on BlePlatformDelegate.
76
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);
89
90     // ===== Members that implement virtual methods on BleApplicationDelegate.
91
92     void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId);
93
94     // ===== Private members reserved for use by this class only.
95
96     enum class Flags : uint8_t
97     {
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. */
104     };
105
106     struct ServiceData;
107
108     BitFlags<Flags> mFlags;
109     uint16_t mGAPConns;
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;
114
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();
128
129     static void DriveBLEState(intptr_t arg);
130
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);
136
137     // ===== Members for internal use by the following friends.
138
139     friend BLEManager & BLEMgr(void);
140     friend BLEManagerImpl & BLEMgrImpl(void);
141
142     static BLEManagerImpl sInstance;
143
144 public:
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,
147                                  uint8_t flags);
148     static ssize_t HandleTXCCCWrite(bt_conn * conn, const bt_gatt_attr * attr, uint16_t value);
149 };
150
151 /**
152  * Returns a reference to the public interface of the BLEManager singleton object.
153  *
154  * Internal components should use this to access features of the BLEManager object
155  * that are common to all platforms.
156  */
157 inline BLEManager & BLEMgr(void)
158 {
159     return BLEManagerImpl::sInstance;
160 }
161
162 /**
163  * Returns the platform-specific implementation of the BLEManager singleton object.
164  *
165  * Internal components can use this to gain access to features of the BLEManager
166  * that are specific to the Zephyr platforms.
167  */
168 inline BLEManagerImpl & BLEMgrImpl(void)
169 {
170     return BLEManagerImpl::sInstance;
171 }
172
173 inline BleLayer * BLEManagerImpl::_GetBleLayer()
174 {
175     return this;
176 }
177
178 inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void)
179 {
180     return mServiceMode;
181 }
182
183 inline bool BLEManagerImpl::_IsAdvertisingEnabled(void)
184 {
185     return mFlags.Has(Flags::kAdvertisingEnabled);
186 }
187
188 inline bool BLEManagerImpl::_IsFastAdvertisingEnabled(void)
189 {
190     return mFlags.Has(Flags::kFastAdvertisingEnabled);
191 }
192
193 inline bool BLEManagerImpl::_IsAdvertising(void)
194 {
195     return mFlags.Has(Flags::kAdvertising);
196 }
197
198 } // namespace Internal
199 } // namespace DeviceLayer
200 } // namespace chip
201
202 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE