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

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.