forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBleLayer.h
332 lines (286 loc) · 15.3 KB
/
BleLayer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/*
*
* Copyright (c) 2020-2021 Project CHIP Authors
* Copyright (c) 2014-2017 Nest Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file defines objects that provide an abstraction layer between a
* platform's Bluetooth Low Energy (BLE) implementation and the CHIP
* stack.
*
* The BleLayer object accepts BLE data and control input from the
* application via a functional interface. It performs the fragmentation
* and reassembly required to transmit CHIP message via a BLE GATT
* characteristic interface, and drives incoming messages up the CHIP
* stack.
*
* During initialization, the BleLayer object requires a pointer to the
* platform's implementation of the BleAdapter object. This object is
* defined but not implemented by the CHIP stack, and provides the
* BleLayer with a functional interface to drive outgoing GATT
* characteristic writes and indications. It also provides a mechanism
* for CHIP to inform the application when it has finished using a given
* BLE connection, i.e., when the chipConnection object wrapping this
* connection has closed.
*
* To enable CHIP over BLE for a new platform, the application developer
* must implement the BleAdapter class for their platform, pass it to the
* BleLayer on startup, pass a pointer to this BleLayer to their instance
* of chipMessageLayer, and ensure that the application calls the
* necessary BleLayer functions to drive BLE data and control input up the
* stack.
*/
#pragma once
#ifndef _CHIP_BLE_BLE_H
#error "Please include <ble/Ble.h> instead!"
#endif
#include <cstddef>
#include <cstdint>
#include <lib/core/CHIPError.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/SetupDiscriminator.h>
#include <system/SystemLayer.h>
#include <system/SystemPacketBuffer.h>
#include "BleApplicationDelegate.h"
#include "BleConfig.h"
#include "BleConnectionDelegate.h"
#include "BleLayerDelegate.h"
#include "BlePlatformDelegate.h"
#include "BleRole.h"
#include "BleUUID.h"
namespace chip {
namespace Ble {
/**
* @def NUM_SUPPORTED_PROTOCOL_VERSIONS
*
* Number of unsigned 4-bit representations of supported transport protocol
* versions encapsulated in a BleTransportCapabilitiesRequest. Defined by CHIP
* over BLE protocol specification.
*/
#define NUM_SUPPORTED_PROTOCOL_VERSIONS 8
/// Version(s) of the CHIP BLE Transport Protocol that this stack supports.
#define CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION kBleTransportProtocolVersion_V4
#define CHIP_BLE_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION kBleTransportProtocolVersion_V4
/// Enum defining versions of CHIP over BLE transport protocol.
typedef enum
{
kBleTransportProtocolVersion_None = 0,
kBleTransportProtocolVersion_V4 = 4 // BTP as defined by CHIP v1.0
} BleTransportProtocolVersion;
inline constexpr size_t kCapabilitiesRequestMagicnumLength = 2;
inline constexpr size_t kCapabilitiesRequestL2capMtuLength = 2;
inline constexpr size_t kCapabilitiesRequestSupportedVersionsLength = 4;
inline constexpr size_t kCapabilitiesRequestWindowSizeLength = 1;
constexpr size_t kCapabilitiesRequestLength = (kCapabilitiesRequestMagicnumLength + kCapabilitiesRequestL2capMtuLength +
kCapabilitiesRequestSupportedVersionsLength + kCapabilitiesRequestWindowSizeLength);
inline constexpr size_t kCapabilitiesResponseMagicnumLength = 2;
inline constexpr size_t kCapabilitiesResponseL2capMtuLength = 2;
inline constexpr size_t kCapabilitiesResponseSelectedProtocolVersionLength = 1;
inline constexpr size_t kCapabilitiesResponseWindowSizeLength = 1;
constexpr size_t kCapabilitiesResponseLength(kCapabilitiesResponseMagicnumLength + kCapabilitiesResponseL2capMtuLength +
kCapabilitiesResponseSelectedProtocolVersionLength +
kCapabilitiesResponseWindowSizeLength);
class BleTransportCapabilitiesRequestMessage
{
public:
/**
* An array of size NUM_SUPPORTED_PROTOCOL_VERSIONS listing versions of the
* BLE transport protocol that this node supports. Each protocol version is
* specified as a 4-bit unsigned integer. A zero-value represents unused
* array elements. Counting up from the zero-index, the first zero-value
* specifies the end of the list of supported protocol versions.
*/
uint8_t mSupportedProtocolVersions[(NUM_SUPPORTED_PROTOCOL_VERSIONS / 2) + (NUM_SUPPORTED_PROTOCOL_VERSIONS % 2)];
/**
* The MTU that has been negotiated for this BLE connection. Specified in
* the BleTransportCapabilitiesRequestMessage because the remote node may
* be unable to glean this info from its own BLE hardware/software stack,
* such as on older Android platforms.
*
* A value of 0 means that the central could not determine the negotiated
* BLE connection MTU.
*/
uint16_t mMtu;
/**
* The initial and maximum receive window size offered by the central,
* defined in terms of GATT indication payloads.
*/
uint8_t mWindowSize;
/**
* Set supported version value at given index in
* SupportedProtocolVersions. uint8_t version argument is truncated to 4
* least-significant bits. Index shall be 0 through number of
* SupportedProtocolVersions elements - 1.
*/
void SetSupportedProtocolVersion(uint8_t index, uint8_t version);
/// Must be able to reserve 20 byte data length in msgBuf.
CHIP_ERROR Encode(const System::PacketBufferHandle & msgBuf) const;
static CHIP_ERROR Decode(const System::PacketBufferHandle & msgBuf, BleTransportCapabilitiesRequestMessage & msg);
};
class BleTransportCapabilitiesResponseMessage
{
public:
/**
* The lower 4 bits specify the BLE transport protocol version that the BLE
* peripheral has selected for this connection.
*
* A value of kBleTransportProtocolVersion_None means that no supported
* protocol version was found in the central's capabilities request. The
* central should unsubscribe after such a response has been sent to free
* up the peripheral for connections from devices with supported protocol
* versions.
*/
uint8_t mSelectedProtocolVersion;
/**
* BLE transport fragment size selected by peripheral in response to MTU
* value in BleTransportCapabilitiesRequestMessage and its local
* observation of the BLE connection MTU.
*/
uint16_t mFragmentSize;
/**
* The initial and maximum receive window size offered by the peripheral,
* defined in terms of GATT write payloads.
*/
uint8_t mWindowSize;
/// Must be able to reserve 20 byte data length in msgBuf.
CHIP_ERROR Encode(const System::PacketBufferHandle & msgBuf) const;
static CHIP_ERROR Decode(const System::PacketBufferHandle & msgBuf, BleTransportCapabilitiesResponseMessage & msg);
};
/**
* @class BleLayer
*
* @brief
* This class provides an interface for a single thread to drive data
* either up the stack via the BleLayer platform interface functions,
* or down the stack via a chipConnection object associated with a
* BLEEndPoint.
*
* There are two ways to associate a chipConnection (defined by the
* chipMessageLayer) with a BLE connection:
*
* First, the application can passively receive an incoming BLE connection
* and hand the platform-specific BLE_CONNECTION_OBJECT that this receipt
* generates to BleLayer via the corresponding platform interface function.
* This causes BleLayer to wrap the BLE_CONNECTION_OBJECT in a BLEEndPoint,
* and notify chipMessageLayer that a new BLE connection has been received.
* The message layer then wraps the new BLEEndPoint object in a
* chipConnection, and hands this object to the application via the message
* layer's OnConnectionReceived callback.
*
* Second, the application can actively form an outgoing BLE connection, e.g.,
* by connecting to a BLE peripheral. It then creates a new chipConnection
* via the chipMessageLayer, assigns an authentication type to this
* connection, and binds it to the BLE_CONNECTION_OBJECT for the new BLE
* connection via chipConnection::ConnectBle. This function then
* establishes the secure session type specified by the chipConnection's
* authentication type member variable.
*
*/
class DLL_EXPORT BleLayer
{
friend class BLEEndPoint;
public:
// Public data members:
enum
{
kState_NotInitialized = 0,
kState_Initialized = 1,
kState_Disconnecting = 2
} mState; ///< [READ-ONLY] Current state
// This app state is not used by ble transport etc, it will be used by external ble implementation like Android
void * mAppState = nullptr;
BleLayerDelegate * mBleTransport = nullptr;
// Public functions:
BleLayer();
CHIP_ERROR Init(BlePlatformDelegate * platformDelegate, BleApplicationDelegate * appDelegate,
chip::System::Layer * systemLayer);
CHIP_ERROR Init(BlePlatformDelegate * platformDelegate, BleConnectionDelegate * connDelegate,
BleApplicationDelegate * appDelegate, chip::System::Layer * systemLayer);
void IndicateBleClosing();
void Shutdown();
CHIP_ERROR CancelBleIncompleteConnection();
CHIP_ERROR NewBleConnectionByDiscriminator(const SetupDiscriminator & connDiscriminator, void * appState = nullptr,
BleConnectionDelegate::OnConnectionCompleteFunct onSuccess = OnConnectionComplete,
BleConnectionDelegate::OnConnectionErrorFunct onError = OnConnectionError);
CHIP_ERROR NewBleConnectionByObject(BLE_CONNECTION_OBJECT connObj, void * appState,
BleConnectionDelegate::OnConnectionCompleteFunct onSuccess = OnConnectionComplete,
BleConnectionDelegate::OnConnectionErrorFunct onError = OnConnectionError);
CHIP_ERROR NewBleConnectionByObject(BLE_CONNECTION_OBJECT connObj);
CHIP_ERROR NewBleEndPoint(BLEEndPoint ** retEndPoint, BLE_CONNECTION_OBJECT connObj, BleRole role, bool autoClose);
void CloseAllBleConnections();
void CloseBleConnection(BLE_CONNECTION_OBJECT connObj);
/**< Platform interface functions:
* Calling conventions:
* CHIP takes ownership of PacketBuffers received through these functions,
* and will free them or pass ownership up the stack.
*
* Beyond each call, no guarantees are provided as to the lifetime of UUID arguments.
*
* A 'true' return value means the CHIP stack successfully handled the corresponding message
* or state indication. 'false' means the CHIP stack either failed or chose not to handle this.
* This contract allows the platform to pass BLE events to CHIP without needing to know which
* characteristics CHIP cares about.
* Platform must call this function when a GATT subscription has been established to any CHIP service
* characteristic.
*
* If this function returns true, CHIP has accepted the BLE connection and wrapped it
* in a chipConnection object. If CHIP accepts a BLE connection, the platform MUST
* notify CHIP if the subscription is canceled or the underlying BLE connection is
* closed, or the associated chipConnection will never be closed or freed. */
bool HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);
/// Call when a GATT subscribe request succeeds.
bool HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);
/**< Platform must call this function when a GATT unsubscribe is requested on any CHIP
* service characteristic, that is, when an existing GATT subscription on a CHIP service
* characteristic is canceled. */
bool HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);
/// Call when a GATT unsubscribe request succeeds.
bool HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);
/// Call when a GATT write request is received.
bool HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
System::PacketBufferHandle && pBuf);
/// Call when a GATT indication is received.
bool HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
System::PacketBufferHandle && pBuf);
/// Call when an outstanding GATT write request receives a positive receipt confirmation.
bool HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);
/// Call when an outstanding GATT indication receives a positive receipt confirmation.
bool HandleIndicationConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);
/**< Platform must call this function when any previous operation undertaken by the BleLayer via BleAdapter
* fails, such as a characteristic write request or subscribe attempt, or when a BLE connection is closed.
*
* In most cases, this will prompt CHIP to close the associated chipConnection and notify that platform that
* it has abandoned the underlying BLE connection.
*
* NOTE: if the application explicitly closes a BLE connection with an associated chipConnection such that
* the BLE connection close will not generate an upcall to CHIP, HandleConnectionError must be called with
* err = BLE_ERROR_APP_CLOSED_CONNECTION to prevent the leak of this chipConnection and its end point object. */
void HandleConnectionError(BLE_CONNECTION_OBJECT connObj, CHIP_ERROR err);
private:
// Private data members:
BleConnectionDelegate * mConnectionDelegate;
BlePlatformDelegate * mPlatformDelegate;
BleApplicationDelegate * mApplicationDelegate;
chip::System::Layer * mSystemLayer;
// Private functions:
void HandleAckReceived(BLE_CONNECTION_OBJECT connObj);
CHIP_ERROR HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT connObj, System::PacketBufferHandle && pBuf);
static BleTransportProtocolVersion GetHighestSupportedProtocolVersion(const BleTransportCapabilitiesRequestMessage & reqMsg);
static void OnConnectionComplete(void * appState, BLE_CONNECTION_OBJECT connObj);
static void OnConnectionError(void * appState, CHIP_ERROR err);
};
} /* namespace Ble */
} /* namespace chip */