Mistake on this page?
Report an issue in GitHub or email us
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 
26 namespace 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 
136 public:
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  */
312  uint8_t getNumberOfEnabledPhys() const
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 
384 private:
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 
469 private:
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__ */
ConnectionParameters & setFilter(initiator_filter_policy_t filterPolicy)
Set if the whitelist should be used to find the peer.
LayoutType value() const
Explicit access to the inner value of the SafeEnum instance.
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.
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.
Type that describe a set of PHY(sical) transports.
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.
uint8_t getNumberOfEnabledPhys() const
Return the number of PHY enabled.
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.
Entry namespace for all BLE API definitions.
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.