Mbed OS Reference
Loading...
Searching...
No Matches
ConnectionParameters.h
1/* mbed Microcontroller Library
2 * Copyright (c) 2006-2020 ARM Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#ifndef MBED_EXTENDED_CONNECT_PARAMETERS_H__
20#define MBED_EXTENDED_CONNECT_PARAMETERS_H__
21
22#include "platform/mbed_assert.h"
23
24#include "ble/common/BLETypes.h"
25
26namespace ble {
27
28/**
29 * @addtogroup ble
30 * @{
31 * @addtogroup gap
32 * @{
33 */
34
35/**
36 * Parameters defining the connection initiation process.
37 *
38 * The connection initiation process is divided in two different phases. First,
39 * the initiating device scans for the peer to which it should connect. Once it finds
40 * the peer, it sends a connection request that contains the connection
41 * parameters.
42 *
43 * @par Scan parameters
44 *
45 * The scan parameters are defined by two durations: the scan interval and the
46 * scan window. The scan interval is the duration between two scan cycles, and the
47 * scan window defines how long the device searches during a scan cycle.
48 *
49 * You can set the scan window and the scan interval at construction time or by
50 * calling setScanParameters().
51 *
52 * @par Connection parameters
53 *
54 * A Bluetooth connection is defined by three parameters:
55 * - Connection interval: The time between two connection events. A minimum
56 * and a maximum connection interval are requested to help the Bluetooth
57 * subsystem deal with concurrent radio processing.
58 * - Slave latency: Number of connection events that can be ignored by the
59 * slave.
60 * - Supervision timeout: Time after which the connection is considered lost
61 * if the connected devices haven't exchanged a single packet. It is important
62 * to note that even if the application doesn't send actual data, the Bluetooth
63 * controller takes care of sending empty data packets to maintain the
64 * connection.
65 *
66 * You can set these parameters at construction time or by calling the function
67 * setConnectionParameters().
68 *
69 * @par PHY
70 *
71 * Bluetooth 5 has introduced the support of different physical layer to either
72 * increase the range or the throughput. You can configure multiple PHY
73 * independently for scanning and connecting.
74 *
75 * Legacy connection happens on the 1M PHY (phy_t::LE_1M). It is the only PHY
76 * that you can configure on legacy systems.
77 *
78 * The constructor, setScanParameters() and setConnectionParameters() accept
79 * a phy_t parameter that defines to which PHY the parameters set applies.
80 *
81 * @par Other parameters:
82 *
83 * It is possible to define what type of address is used to establish the
84 * connection and whether the whitelist should be used to find the peer
85 * to connect to.
86 *
87 * @par Example:
88 *
89 * Thanks to the fluent API, you can compose the connection parameters at
90 * instantiation point:
91 *
92 * @code
93 *
94 void do_connect(ble::Gap& gap, ble::target_peer_address_type_t addr_type, ble::address_t& address)
95 {
96 using namespace ble;
97
98 gap.connect(
99 addr_type,
100 address,
101 ConnectionParameters()
102 .setScanParameters(
103 phy_t::LE_1M,
104 scan_interval_t(millisecond_t(500)),
105 scan_window_t(millisecond_t(250))
106 )
107 .setConnectionParameters(
108 phy_t::LE_1M,
109 conn_interval_t(millisecond_t(100)),
110 conn_interval_t(millisecond_t(200)),
111 slave_latency_t(0),
112 supervision_timeout_t(millisecond_t(1000))
113 )
114 .setOwnAddressType(own_address_type_t::RANDOM)
115 );
116 }
117 *
118 * @endcode
119 *
120 * @note It is not possible to configure phy_t::LE_2M for scanning.
121 *
122 * @see ble::Gap::connect()
123 */
125 enum {
126 LE_1M_INDEX = 0,
127 LE_2M_INDEX = 1,
128 LE_CODED_INDEX = 2,
129#if BLE_FEATURE_PHY_MANAGEMENT
130 MAX_PARAM_PHYS = 3
131#else
132 MAX_PARAM_PHYS = 1
133#endif // BLE_FEATURE_PHY_MANAGEMENT
134 };
135
136public:
137 /**
138 * Create a ConnectionParameters object.
139 *
140 * @param phy The PHY being configured.
141 * @param scanInterval Interval between two scans.
142 * @param scanWindow Scan duration during a scan interval.
143 * @param minConnectionInterval Minimum value of the connection interval.
144 * @param maxConnectionInterval Maximum value of the connection interval.
145 * @param slaveLatency Maximum number of packets the slave can drop.
146 * @param connectionSupervisionTimeout Time after which the connection is
147 * considered lost if no data has been exchanged.
148 * @param minEventLength Minimum duration of a connection event.
149 * @param maxEventLength Maximum duration of a connection event.
150 */
152 phy_t phy = phy_t::LE_1M,
153 scan_interval_t scanInterval = scan_interval_t::min(),
154 scan_window_t scanWindow = scan_window_t::min(),
155 conn_interval_t minConnectionInterval = conn_interval_t(50),
156 conn_interval_t maxConnectionInterval = conn_interval_t(100),
157 slave_latency_t slaveLatency = slave_latency_t::min(),
158 supervision_timeout_t connectionSupervisionTimeout = supervision_timeout_t(100),
159 conn_event_length_t minEventLength = conn_event_length_t::min(),
160 conn_event_length_t maxEventLength = conn_event_length_t::max()
161 );
162
163 /* setters */
164
165 /**
166 * Set the scan parameters for a given PHY.
167 *
168 * @param phy PHY being configured.
169 * @param scanInterval Interval between two scans.
170 * @param scanWindow Scan duration within a scan interval.
171 *
172 * @note It is useless to configure the 2M PHY because it is not used during
173 * scanning.
174 *
175 * @return A reference to this.
176 */
178 phy_t phy,
179 scan_interval_t scanInterval,
180 scan_window_t scanWindow
181 );
182
183 /**
184 * Set the conenction parameters of a given PHY.
185 *
186 * @param phy The PHY being configured.
187 * @param minConnectionInterval Minimum connection interval.
188 * @param maxConnectionInterval Maximum connection interval.
189 * @param slaveLatency Maximum number of packets the slave can drop.
190 * @param connectionSupervisionTimeout Time after which the connection is
191 * considered lost if no data has been exchanged.
192 * @param minEventLength Minimum duration of a connection event.
193 * @param maxEventLength Maximum duration of a connection event.
194 *
195 * @return A reference to this.
196 */
198 phy_t phy,
199 conn_interval_t minConnectionInterval,
200 conn_interval_t maxConnectionInterval,
201 slave_latency_t slaveLatency,
202 supervision_timeout_t connectionSupervisionTimeout,
203 conn_event_length_t minEventLength = conn_event_length_t::min(),
204 conn_event_length_t maxEventLength = conn_event_length_t::max()
205 );
206
207 /**
208 * Address type used by the local device to connect the peer.
209 * @param ownAddress Type of address used to initiate the connection.
210 * @return A reference to this.
211 */
212 ConnectionParameters &setOwnAddressType(own_address_type_t ownAddress)
213 {
214 _ownAddressType = ownAddress;
215 return *this;
216 }
217
218 /**
219 * Set if the whitelist should be used to find the peer.
220 *
221 * @param filterPolicy The initiator filter to apply.
222 *
223 * @return A reference to this.
224 */
225 ConnectionParameters &setFilter(initiator_filter_policy_t filterPolicy)
226 {
227#if BLE_FEATURE_WHITELIST
228 _filterPolicy = filterPolicy;
229#endif // BLE_FEATURE_WHITELIST
230 return *this;
231 }
232
233 /**
234 * Enable or disable PHYs.
235 *
236 * @param phy1M true to enable the 1M PHY and false to disable it.
237 * @param phy2M true to enable the 2M PHY and false to disable it.
238 * @param phyCoded true to enable the CODED PHY and false to disable it.
239 *
240 * @return A reference to this.
241 */
242 ConnectionParameters &togglePhy(bool phy1M, bool phy2M, bool phyCoded)
243 {
244#if BLE_FEATURE_PHY_MANAGEMENT
245 handlePhyToggle(phy_t::LE_1M, phy1M);
246 handlePhyToggle(phy_t::LE_2M, phy2M);
247 handlePhyToggle(phy_t::LE_CODED, phyCoded);
248#endif // BLE_FEATURE_PHY_MANAGEMENT
249 return *this;
250 }
251
252 /**
253 * Disable an individual PHY.
254 *
255 * @param phy The PHY to disable.
256 *
257 * @return A reference to this.
258 */
260 {
261#if BLE_FEATURE_PHY_MANAGEMENT
262 handlePhyToggle(phy, false);
263#endif // BLE_FEATURE_PHY_MANAGEMENT
264 return *this;
265 }
266
267 /**
268 * Enable an individual PHY.
269 *
270 * @param phy The PHY to enable.
271 *
272 * @return A reference to this.
273 */
275 {
276#if BLE_FEATURE_PHY_MANAGEMENT
277 handlePhyToggle(phy, true);
278#endif // BLE_FEATURE_PHY_MANAGEMENT
279 return *this;
280 }
281
282 /* getters */
283
284 /**
285 * Return the local address type used.
286 *
287 * @return The local address type to use.
288 */
289 own_address_type_t getOwnAddressType() const
290 {
291 return _ownAddressType;
292 }
293
294 /**
295 * Return the initiator policy.
296 *
297 * @return The initiator policy.
298 */
299 initiator_filter_policy_t getFilter() const
300 {
301#if BLE_FEATURE_WHITELIST
302 return _filterPolicy;
303#else
304 return initiator_filter_policy_t::NO_FILTER;
305#endif // BLE_FEATURE_WHITELIST
306 }
307
308 /**
309 * Return the number of PHY enabled.
310 * @return The number of PHY enabled.
311 */
313 {
314 return (
315 _enabledPhy[LE_1M_INDEX] * 1
316#if BLE_FEATURE_PHY_MANAGEMENT
317 + _enabledPhy[LE_2M_INDEX] * 1
318 + _enabledPhy[LE_CODED_INDEX] * 1
319#endif // BLE_FEATURE_PHY_MANAGEMENT
320 );
321 }
322
323#if !defined(DOXYGEN_ONLY)
324
325 phy_set_t getPhySet() const
326 {
327#if BLE_FEATURE_PHY_MANAGEMENT
328 phy_set_t set(
329 _enabledPhy[LE_1M_INDEX],
330 _enabledPhy[LE_2M_INDEX],
331 _enabledPhy[LE_CODED_INDEX]
332 );
333 return set;
334#else
335 return phy_set_t::PHY_SET_1M;
336#endif // BLE_FEATURE_PHY_MANAGEMENT
337 }
338
339
340 /* These return pointers to arrays of settings valid only across the number of active PHYs */
341
342 const uint16_t *getScanIntervalArray() const
343 {
344 return &_scanInterval[getFirstEnabledIndex()];
345 }
346
347 const uint16_t *getScanWindowArray() const
348 {
349 return &_scanWindow[getFirstEnabledIndex()];
350 }
351
352 const uint16_t *getMinConnectionIntervalArray() const
353 {
354 return &_minConnectionInterval[getFirstEnabledIndex()];
355 }
356
357 const uint16_t *getMaxConnectionIntervalArray() const
358 {
359 return &_maxConnectionInterval[getFirstEnabledIndex()];
360 }
361
362 const uint16_t *getSlaveLatencyArray() const
363 {
364 return &_slaveLatency[getFirstEnabledIndex()];
365 }
366
367 const uint16_t *getConnectionSupervisionTimeoutArray() const
368 {
369 return &_connectionSupervisionTimeout[getFirstEnabledIndex()];
370 }
371
372 const uint16_t *getMinEventLengthArray() const
373 {
374 return &_minEventLength[getFirstEnabledIndex()];
375 }
376
377 const uint16_t *getMaxEventLengthArray() const
378 {
379 return &_maxEventLength[getFirstEnabledIndex()];
380 }
381
382#endif
383
384private:
385 uint8_t getFirstEnabledIndex() const
386 {
387#if BLE_FEATURE_PHY_MANAGEMENT
388 if (_enabledPhy[LE_1M_INDEX]) {
389 return LE_1M_INDEX;
390 } else if (_enabledPhy[LE_2M_INDEX]) {
391 return LE_2M_INDEX;
392 } else if (_enabledPhy[LE_CODED_INDEX]) {
393 return LE_CODED_INDEX;
394 }
395 /* This should never happen; it means you were trying to start a connection with a blank set
396 * of parameters - you need to enable at least one PHY */
397 MBED_ASSERT("Trying to use connection parameters without any PHY defined.");
398#endif // BLE_FEATURE_PHY_MANAGEMENT
399 return 0;
400 }
401
402 /** Handle toggling PHYs on and off and return the correct index to use to set the configuration elements.
403 *
404 * @param phy Which PHY is being toggled.
405 * @param enable On or Off.
406 * @return The index to the array of settings.
407 */
408 uint8_t handlePhyToggle(phy_t phy, bool enable)
409 {
410 uint8_t index = phyToIndex(phy);
411
412#if BLE_FEATURE_PHY_MANAGEMENT
413 bool was_swapped = isSwapped();
414
415 _enabledPhy[index] = enable;
416
417 bool is_swapped = isSwapped();
418
419 if (was_swapped != is_swapped) {
420 swapCodedAnd2M();
421 }
422
423 if (is_swapped && index == LE_CODED_INDEX) {
424 /* To keep the data contiguous, coded params are in place of the missing 2M params */
425 index = LE_2M_INDEX;
426 }
427#endif // BLE_FEATURE_PHY_MANAGEMENT
428
429 return index;
430 }
431
432 static uint8_t phyToIndex(phy_t phy)
433 {
434 uint8_t index;
435 switch (phy.value()) {
436 case phy_t::LE_1M:
437 index = LE_1M_INDEX;
438 break;
439#if BLE_FEATURE_PHY_MANAGEMENT
440 case phy_t::LE_2M:
441 index = LE_2M_INDEX;
442 break;
443 case phy_t::LE_CODED:
444 index = LE_CODED_INDEX;
445 break;
446#endif // BLE_FEATURE_PHY_MANAGEMENT
447 default:
448 index = LE_1M_INDEX;
449 MBED_ASSERT("Illegal PHY");
450 break;
451 }
452 return index;
453 }
454
455#if BLE_FEATURE_PHY_MANAGEMENT
456 bool isSwapped() const
457 {
458 return (
459 _enabledPhy[LE_1M_INDEX] &&
460 !_enabledPhy[LE_2M_INDEX] &&
461 _enabledPhy[LE_CODED_INDEX]
462 );
463 }
464
465 /** Handle the swapping of 2M and CODED so that the array is ready for the pal call. */
466 void swapCodedAnd2M();
467#endif // BLE_FEATURE_PHY_MANAGEMENT
468
469private:
470 initiator_filter_policy_t _filterPolicy;
471 own_address_type_t _ownAddressType;
472
473 uint16_t _scanInterval[MAX_PARAM_PHYS]; /* 0.625 ms */
474 uint16_t _scanWindow[MAX_PARAM_PHYS]; /* 0.625 ms */
475 uint16_t _minConnectionInterval[MAX_PARAM_PHYS]; /* 1.25 ms */
476 uint16_t _maxConnectionInterval[MAX_PARAM_PHYS]; /* 1.25 ms */
477 uint16_t _slaveLatency[MAX_PARAM_PHYS]; /* events */
478 uint16_t _connectionSupervisionTimeout[MAX_PARAM_PHYS]; /* 10 ms */
479 uint16_t _minEventLength[MAX_PARAM_PHYS]; /* 0.625 ms */
480 uint16_t _maxEventLength[MAX_PARAM_PHYS]; /* 0.625 ms */
481
482 bool _enabledPhy[MAX_PARAM_PHYS];
483};
484
485/**
486 * @}
487 * @}
488 */
489
490} // namespace ble
491
492#endif /* ifndef MBED_EXTENDED_CONNECT_PARAMETERS_H__ */
Parameters defining the connection initiation process.
ConnectionParameters & togglePhy(bool phy1M, bool phy2M, bool phyCoded)
Enable or disable PHYs.
ConnectionParameters & setScanParameters(phy_t phy, scan_interval_t scanInterval, scan_window_t scanWindow)
Set the scan parameters for a given PHY.
ConnectionParameters(phy_t phy=phy_t::LE_1M, scan_interval_t scanInterval=scan_interval_t::min(), scan_window_t scanWindow=scan_window_t::min(), conn_interval_t minConnectionInterval=conn_interval_t(50), conn_interval_t maxConnectionInterval=conn_interval_t(100), slave_latency_t slaveLatency=slave_latency_t::min(), supervision_timeout_t connectionSupervisionTimeout=supervision_timeout_t(100), conn_event_length_t minEventLength=conn_event_length_t::min(), conn_event_length_t maxEventLength=conn_event_length_t::max())
Create a ConnectionParameters object.
ConnectionParameters & setConnectionParameters(phy_t phy, conn_interval_t minConnectionInterval, conn_interval_t maxConnectionInterval, slave_latency_t slaveLatency, supervision_timeout_t connectionSupervisionTimeout, conn_event_length_t minEventLength=conn_event_length_t::min(), conn_event_length_t maxEventLength=conn_event_length_t::max())
Set the conenction parameters of a given PHY.
own_address_type_t getOwnAddressType() const
Return the local address type used.
ConnectionParameters & setFilter(initiator_filter_policy_t filterPolicy)
Set if the whitelist should be used to find the peer.
initiator_filter_policy_t getFilter() const
Return the initiator policy.
ConnectionParameters & disablePhy(phy_t phy=phy_t::LE_1M)
Disable an individual PHY.
ConnectionParameters & setOwnAddressType(own_address_type_t ownAddress)
Address type used by the local device to connect the peer.
uint8_t getNumberOfEnabledPhys() const
Return the number of PHY enabled.
ConnectionParameters & enablePhy(phy_t phy=phy_t::LE_1M)
Enable an individual PHY.
Type that describe a set of PHY(sical) transports.
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:66
Entry namespace for all BLE API definitions.
Type that describes a bluetooth PHY(sical) transport.
@ LE_2M
2Mbit/s LE.
@ LE_1M
1Mbit/s LE.
@ LE_CODED
LE Coded PHY.