Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ConnectionParameters.h Source File

ConnectionParameters.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015 */
00016 
00017 #ifndef MBED_EXTENDED_CONNECT_PARAMETERS_H__
00018 #define MBED_EXTENDED_CONNECT_PARAMETERS_H__
00019 
00020 #include "ble/BLETypes.h"
00021 #include "mbed_assert.h"
00022 
00023 namespace ble {
00024 
00025 /**
00026  * @addtogroup ble
00027  * @{
00028  * @addtogroup gap
00029  * @{
00030  */
00031 
00032 /**
00033  * Parameters defining the connection initiation process.
00034  *
00035  * The connection initiation process is divided in two different phases. First,
00036  * the initiating device scans for the peer to which it should connect. Once it finds
00037  * the peer, it sends a connection request that contains the connection
00038  * parameters.
00039  *
00040  * @par Scan parameters
00041  *
00042  * The scan parameters are defined by two durations: the scan interval and the
00043  * scan window. The scan interval is the duration between two scan cycles, and the
00044  * scan window defines how long the device searches during a scan cycle.
00045  *
00046  * You can set the scan window and the scan interval at construction time or by
00047  * calling setScanParameters().
00048  *
00049  * @par Connection parameters
00050  *
00051  * A Bluetooth connection is defined by three parameters:
00052  *   - Connection interval: The time between two connection events. A minimum
00053  *   and a maximum connection interval are requested to help the Bluetooth
00054  *   subsystem deal with concurrent radio processing.
00055  *   - Slave latency: Number of connection events that can be ignored by the
00056  *   slave.
00057  *   - Supervision timeout: Time after which the connection is considered lost
00058  *   if the connected devices haven't exchanged a single packet. It is important
00059  *   to note that even if the application doesn't send actual data, the Bluetooth
00060  *   controller takes care of sending empty data packets to maintain the
00061  *   connection.
00062  *
00063  * You can set these parameters at construction time or by calling the function
00064  * setConnectionParameters().
00065  *
00066  * @par PHY
00067  *
00068  * Bluetooth 5 has introduced the support of different physical layer to either
00069  * increase the range or the throughput. You can configure multiple PHY
00070  * independently for scanning and connecting.
00071  *
00072  * Legacy connection happens on the 1M PHY (phy_t::LE_1M). It is the only PHY
00073  * that you can configure on legacy systems.
00074  *
00075  * The constructor, setScanParameters() and setConnectionParameters() accept
00076  * a phy_t parameter that defines to which PHY the parameters set applies.
00077  *
00078  * @par Other parameters:
00079  *
00080  * It is possible to define what type of address is used to establish the
00081  * connection and whether the whitelist should be used to find the peer
00082  * to connect to.
00083  *
00084  * @par Example:
00085  *
00086  * Thanks to the fluent API, you can compose the connection parameters at
00087  * instantiation point:
00088  *
00089  * @code
00090  *
00091     void do_connect(ble::Gap& gap, ble::target_peer_address_type_t addr_type, ble::address_t& address)
00092     {
00093         using namespace ble;
00094 
00095         gap.connect(
00096             addr_type,
00097             address,
00098             ConnectionParameters()
00099                 .setScanParameters(
00100                     phy_t::LE_1M,
00101                     scan_interval_t(millisecond_t(500)),
00102                     scan_window_t(millisecond_t(250))
00103                 )
00104                 .setConnectionParameters(
00105                     phy_t::LE_1M,
00106                     conn_interval_t(millisecond_t(100)),
00107                     conn_interval_t(millisecond_t(200)),
00108                     slave_latency_t(0),
00109                     supervision_timeout_t(millisecond_t(1000))
00110                 )
00111                 .setOwnAddressType(own_address_type_t::RANDOM)
00112         );
00113     }
00114  *
00115  * @endcode
00116  *
00117  * @note It is not possible to configure phy_t::LE_2M for scanning.
00118  *
00119  * @see ble::Gap::connect()
00120  */
00121 class ConnectionParameters {
00122     enum {
00123         LE_1M_INDEX = 0,
00124         LE_2M_INDEX = 1,
00125         LE_CODED_INDEX = 2,
00126 #if BLE_FEATURE_PHY_MANAGEMENT
00127         MAX_PARAM_PHYS = 3
00128 #else
00129         MAX_PARAM_PHYS = 1
00130 #endif // BLE_FEATURE_PHY_MANAGEMENT
00131     };
00132 
00133 public:
00134     /**
00135      * Create a ConnectionParameters object.
00136      *
00137      * @param phy The PHY being configured.
00138      * @param scanInterval Interval between two scans.
00139      * @param scanWindow Scan duration during a scan interval.
00140      * @param minConnectionInterval Minimum value of the connection interval.
00141      * @param maxConnectionInterval Maximum value of the connection interval.
00142      * @param slaveLatency Maximum number of packets the slave can drop.
00143      * @param connectionSupervisionTimeout Time after which the connection is
00144      * considered lost if no data has been exchanged.
00145      * @param minEventLength Minimum duration of a connection event.
00146      * @param maxEventLength Maximum duration of a connection event.
00147      */
00148     ConnectionParameters(
00149         phy_t phy = phy_t::LE_1M,
00150         scan_interval_t  scanInterval = scan_interval_t::min(),
00151         scan_window_t  scanWindow = scan_window_t::min(),
00152         conn_interval_t  minConnectionInterval = conn_interval_t(50),
00153         conn_interval_t  maxConnectionInterval = conn_interval_t(100),
00154         slave_latency_t  slaveLatency = slave_latency_t::min(),
00155         supervision_timeout_t  connectionSupervisionTimeout = supervision_timeout_t(100),
00156         conn_event_length_t minEventLength = conn_event_length_t::min(),
00157         conn_event_length_t maxEventLength = conn_event_length_t::max()
00158     );
00159 
00160     /* setters */
00161 
00162     /**
00163      * Set the scan parameters for a given PHY.
00164      *
00165      * @param phy PHY being configured.
00166      * @param scanInterval Interval between two scans.
00167      * @param scanWindow Scan duration within a scan interval.
00168      *
00169      * @note It is useless to configure the 2M PHY because it is not used during
00170      * scanning.
00171      *
00172      * @return A reference to this.
00173      */
00174     ConnectionParameters &setScanParameters(
00175         phy_t phy,
00176         scan_interval_t  scanInterval,
00177         scan_window_t  scanWindow
00178     );
00179 
00180     /**
00181      * Set the conenction parameters of a given PHY.
00182      *
00183      * @param phy The PHY being configured.
00184      * @param minConnectionInterval Minimum connection interval.
00185      * @param maxConnectionInterval Maximum connection interval.
00186      * @param slaveLatency Maximum number of packets the slave can drop.
00187      * @param connectionSupervisionTimeout Time after which the connection is
00188      * considered lost if no data has been exchanged.
00189      * @param minEventLength Minimum duration of a connection event.
00190      * @param maxEventLength Maximum duration of a connection event.
00191      *
00192      * @return A reference to this.
00193      */
00194     ConnectionParameters &setConnectionParameters(
00195         phy_t phy,
00196         conn_interval_t  minConnectionInterval,
00197         conn_interval_t  maxConnectionInterval,
00198         slave_latency_t  slaveLatency,
00199         supervision_timeout_t  connectionSupervisionTimeout,
00200         conn_event_length_t minEventLength = conn_event_length_t::min(),
00201         conn_event_length_t maxEventLength = conn_event_length_t::max()
00202     );
00203 
00204     /**
00205      * Address type used by the local device to connect the peer.
00206      * @param ownAddress Type of address used to initiate the connection.
00207      * @return A reference to this.
00208      */
00209     ConnectionParameters &setOwnAddressType(own_address_type_t ownAddress)
00210     {
00211         _ownAddressType = ownAddress;
00212         return *this;
00213     }
00214 
00215     /**
00216      * Set if the whitelist should be used to find the peer.
00217      *
00218      * @param filterPolicy The initiator filter to apply.
00219      *
00220      * @return A reference to this.
00221      */
00222     ConnectionParameters &setFilter(initiator_filter_policy_t filterPolicy)
00223     {
00224 #if BLE_FEATURE_WHITELIST
00225         _filterPolicy = filterPolicy;
00226 #endif // BLE_FEATURE_WHITELIST
00227         return *this;
00228     }
00229 
00230     /**
00231      * Enable or disable PHYs.
00232      *
00233      * @param phy1M true to enable the 1M PHY and false to disable it.
00234      * @param phy2M true to enable the 2M PHY and false to disable it.
00235      * @param phyCoded true to enable the CODED PHY and false to disable it.
00236      *
00237      * @return A reference to this.
00238      */
00239     ConnectionParameters &togglePhy(bool phy1M, bool phy2M, bool phyCoded)
00240     {
00241 #if BLE_FEATURE_PHY_MANAGEMENT
00242         handlePhyToggle(phy_t::LE_1M, phy1M);
00243         handlePhyToggle(phy_t::LE_2M, phy2M);
00244         handlePhyToggle(phy_t::LE_CODED, phyCoded);
00245 #endif // BLE_FEATURE_PHY_MANAGEMENT
00246         return *this;
00247     }
00248 
00249     /**
00250      * Disable an individual PHY.
00251      *
00252      * @param phy The PHY to disable.
00253      *
00254      * @return A reference to this.
00255      */
00256     ConnectionParameters &disablePhy(phy_t phy = phy_t::LE_1M)
00257     {
00258 #if BLE_FEATURE_PHY_MANAGEMENT
00259         handlePhyToggle(phy, false);
00260 #endif // BLE_FEATURE_PHY_MANAGEMENT
00261         return *this;
00262     }
00263 
00264     /**
00265      * Enable an individual PHY.
00266      *
00267      * @param phy The PHY to enable.
00268      *
00269      * @return A reference to this.
00270      */
00271     ConnectionParameters &enablePhy(phy_t phy = phy_t::LE_1M)
00272     {
00273 #if BLE_FEATURE_PHY_MANAGEMENT
00274         handlePhyToggle(phy, true);
00275 #endif // BLE_FEATURE_PHY_MANAGEMENT
00276         return *this;
00277     }
00278 
00279     /* getters */
00280 
00281     /**
00282      * Return the local address type used.
00283      *
00284      * @return The local address type to use.
00285      */
00286     own_address_type_t getOwnAddressType() const
00287     {
00288         return _ownAddressType;
00289     }
00290 
00291     /**
00292      * Return the initiator policy.
00293      *
00294      * @return The initiator policy.
00295      */
00296     initiator_filter_policy_t getFilter() const
00297     {
00298 #if BLE_FEATURE_WHITELIST
00299         return _filterPolicy;
00300 #else
00301         return initiator_filter_policy_t::NO_FILTER;
00302 #endif // BLE_FEATURE_WHITELIST
00303     }
00304 
00305     /**
00306      * Return the number of PHY enabled.
00307      * @return The number of PHY enabled.
00308      */
00309     uint8_t getNumberOfEnabledPhys() const
00310     {
00311         return (
00312             _enabledPhy[LE_1M_INDEX] * 1
00313 #if BLE_FEATURE_PHY_MANAGEMENT
00314             + _enabledPhy[LE_2M_INDEX] * 1
00315             + _enabledPhy[LE_CODED_INDEX] * 1
00316 #endif // BLE_FEATURE_PHY_MANAGEMENT
00317         );
00318     }
00319 
00320 #if !defined(DOXYGEN_ONLY)
00321 
00322     phy_set_t getPhySet() const
00323     {
00324 #if BLE_FEATURE_PHY_MANAGEMENT
00325         phy_set_t set(
00326             _enabledPhy[LE_1M_INDEX],
00327             _enabledPhy[LE_2M_INDEX],
00328             _enabledPhy[LE_CODED_INDEX]
00329         );
00330         return set;
00331 #else
00332         return phy_set_t::PHY_SET_1M;
00333 #endif // BLE_FEATURE_PHY_MANAGEMENT
00334     }
00335 
00336 
00337     /* These return pointers to arrays of settings valid only across the number of active PHYs */
00338 
00339     const uint16_t *getScanIntervalArray() const
00340     {
00341         return &_scanInterval[getFirstEnabledIndex()];
00342     }
00343 
00344     const uint16_t *getScanWindowArray() const
00345     {
00346         return &_scanWindow[getFirstEnabledIndex()];
00347     }
00348 
00349     const uint16_t *getMinConnectionIntervalArray() const
00350     {
00351         return &_minConnectionInterval[getFirstEnabledIndex()];
00352     }
00353 
00354     const uint16_t *getMaxConnectionIntervalArray() const
00355     {
00356         return &_maxConnectionInterval[getFirstEnabledIndex()];
00357     }
00358 
00359     const uint16_t *getSlaveLatencyArray() const
00360     {
00361         return &_slaveLatency[getFirstEnabledIndex()];
00362     }
00363 
00364     const uint16_t *getConnectionSupervisionTimeoutArray() const
00365     {
00366         return &_connectionSupervisionTimeout[getFirstEnabledIndex()];
00367     }
00368 
00369     const uint16_t *getMinEventLengthArray() const
00370     {
00371         return &_minEventLength[getFirstEnabledIndex()];
00372     }
00373 
00374     const uint16_t *getMaxEventLengthArray() const
00375     {
00376         return &_maxEventLength[getFirstEnabledIndex()];
00377     }
00378 
00379 #endif
00380 
00381 private:
00382     uint8_t getFirstEnabledIndex() const
00383     {
00384 #if BLE_FEATURE_PHY_MANAGEMENT
00385         if (_enabledPhy[LE_1M_INDEX]) {
00386             return LE_1M_INDEX;
00387         } else if (_enabledPhy[LE_2M_INDEX]) {
00388             return LE_2M_INDEX;
00389         } else if (_enabledPhy[LE_CODED_INDEX]) {
00390             return LE_CODED_INDEX;
00391         }
00392         /* This should never happen; it means you were trying to start a connection with a blank set
00393          * of parameters - you need to enable at least one PHY */
00394         MBED_ASSERT("Trying to use connection parameters without any PHY defined.");
00395 #endif // BLE_FEATURE_PHY_MANAGEMENT
00396         return 0;
00397     }
00398 
00399     /** Handle toggling PHYs on and off and return the correct index to use to set the configuration elements.
00400      *
00401      * @param phy Which PHY is being toggled.
00402      * @param enable On or Off.
00403      * @return The index to the array of settings.
00404      */
00405     uint8_t handlePhyToggle(phy_t phy, bool enable)
00406     {
00407         uint8_t index = phyToIndex(phy);
00408 
00409 #if BLE_FEATURE_PHY_MANAGEMENT
00410         bool was_swapped = isSwapped();
00411 
00412         _enabledPhy[index] = enable;
00413 
00414         bool is_swapped = isSwapped();
00415 
00416         if (was_swapped != is_swapped) {
00417             swapCodedAnd2M();
00418         }
00419 
00420         if (is_swapped && index == LE_CODED_INDEX) {
00421             /* To keep the data contiguous, coded params are in place of the missing 2M params */
00422             index = LE_2M_INDEX;
00423         }
00424 #endif // BLE_FEATURE_PHY_MANAGEMENT
00425 
00426         return index;
00427     }
00428 
00429     uint8_t phyToIndex(phy_t phy) const
00430     {
00431         uint8_t index;
00432         switch (phy.value()) {
00433             case phy_t::LE_1M:
00434                 index = LE_1M_INDEX;
00435                 break;
00436 #if BLE_FEATURE_PHY_MANAGEMENT
00437             case phy_t::LE_2M:
00438                 index = LE_2M_INDEX;
00439                 break;
00440             case phy_t::LE_CODED:
00441                 index = LE_CODED_INDEX;
00442                 break;
00443 #endif // BLE_FEATURE_PHY_MANAGEMENT
00444             default:
00445                 index = LE_1M_INDEX;
00446                 MBED_ASSERT("Illegal PHY");
00447                 break;
00448         }
00449         return index;
00450     }
00451 
00452 #if BLE_FEATURE_PHY_MANAGEMENT
00453     bool isSwapped() const
00454     {
00455         return (
00456             _enabledPhy[LE_1M_INDEX] &&
00457             !_enabledPhy[LE_2M_INDEX] &&
00458             _enabledPhy[LE_CODED_INDEX]
00459         );
00460     }
00461 
00462     /** Handle the swapping of 2M and CODED so that the array is ready for the pal call. */
00463     void swapCodedAnd2M();
00464 #endif // BLE_FEATURE_PHY_MANAGEMENT
00465 
00466 private:
00467     initiator_filter_policy_t _filterPolicy;
00468     own_address_type_t _ownAddressType;
00469 
00470     uint16_t _scanInterval[MAX_PARAM_PHYS]; /* 0.625 ms */
00471     uint16_t _scanWindow[MAX_PARAM_PHYS]; /* 0.625 ms */
00472     uint16_t _minConnectionInterval[MAX_PARAM_PHYS]; /* 1.25 ms */
00473     uint16_t _maxConnectionInterval[MAX_PARAM_PHYS]; /* 1.25 ms */
00474     uint16_t _slaveLatency[MAX_PARAM_PHYS]; /* events */
00475     uint16_t _connectionSupervisionTimeout[MAX_PARAM_PHYS]; /* 10 ms */
00476     uint16_t _minEventLength[MAX_PARAM_PHYS]; /* 0.625 ms */
00477     uint16_t _maxEventLength[MAX_PARAM_PHYS]; /* 0.625 ms */
00478 
00479     bool _enabledPhy[MAX_PARAM_PHYS];
00480 };
00481 
00482 /**
00483  * @}
00484  * @}
00485  */
00486 
00487 } // namespace ble
00488 
00489 #endif /* ifndef MBED_EXTENDED_CONNECT_PARAMETERS_H__ */