Minor fixes

Fork of BLE_API by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Gap.h Source File

Gap.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 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 __GAP_H__
00018 #define __GAP_H__
00019 
00020 #include "GapAdvertisingData.h"
00021 #include "GapAdvertisingParams.h"
00022 #include "GapScanningParams.h"
00023 #include "GapEvents.h"
00024 #include "CallChain.h"
00025 #include "FunctionPointerWithContext.h"
00026 
00027 using namespace mbed;
00028 
00029 /* Forward declarations for classes which will only be used for pointers or references in the following. */
00030 class GapAdvertisingParams;
00031 class GapScanningParams;
00032 class GapAdvertisingData;
00033 
00034 class Gap {
00035 public:
00036     enum AddressType_t {
00037         ADDR_TYPE_PUBLIC = 0,
00038         ADDR_TYPE_RANDOM_STATIC,
00039         ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
00040         ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
00041     };
00042     typedef enum AddressType_t addr_type_t; /* @Note: deprecated. Use AddressType_t instead. */
00043 
00044     static const unsigned ADDR_LEN = 6;
00045     typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */
00046     typedef Address_t address_t;         /* @Note: deprecated. Use Address_t instead. */
00047 
00048     enum TimeoutSource_t {
00049         TIMEOUT_SRC_ADVERTISING      = 0x00, /**< Advertising timeout. */
00050         TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */
00051         TIMEOUT_SRC_SCAN             = 0x02, /**< Scanning timeout. */
00052         TIMEOUT_SRC_CONN             = 0x03, /**< Connection timeout. */
00053     };
00054 
00055     /**
00056      * Enumeration for disconnection reasons. The values for these reasons are
00057      * derived from Nordic's implementation; but the reasons are meant to be
00058      * independent of the transport. If you are returned a reason which is not
00059      * covered by this enumeration, then please refer to the underlying
00060      * transport library.
00061      */
00062     enum DisconnectionReason_t {
00063         CONNECTION_TIMEOUT                          = 0x08,
00064         REMOTE_USER_TERMINATED_CONNECTION           = 0x13,
00065         REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14,  /**< Remote Device Terminated Connection due to low resources.*/
00066         REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF     = 0x15,  /**< Remote Device Terminated Connection due to power off. */
00067         LOCAL_HOST_TERMINATED_CONNECTION            = 0x16,
00068         CONN_INTERVAL_UNACCEPTABLE                  = 0x3B,
00069     };
00070 
00071     /* Describes the current state of the device (more than one bit can be set) */
00072     struct GapState_t {
00073         unsigned advertising : 1; /**< peripheral is currently advertising */
00074         unsigned connected   : 1; /**< peripheral is connected to a central */
00075     };
00076 
00077     typedef uint16_t Handle_t; /* Type for connection handle. */
00078 
00079     typedef struct {
00080         uint16_t minConnectionInterval;      /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
00081         uint16_t maxConnectionInterval;      /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
00082         uint16_t slaveLatency;               /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
00083         uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
00084     } ConnectionParams_t;
00085 
00086     enum Role_t {
00087         PERIPHERAL  = 0x1, /**< Peripheral Role. */
00088         CENTRAL     = 0x2, /**< Central Role.    */
00089     };
00090 
00091     struct AdvertisementCallbackParams_t {
00092         Address_t            peerAddr;
00093         int8_t               rssi;
00094         bool                 isScanResponse;
00095         GapAdvertisingParams::AdvertisingType_t  type;
00096         uint8_t              advertisingDataLen;
00097         const uint8_t       *advertisingData;
00098     };
00099     typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *>  AdvertisementReportCallback_t;
00100 
00101     struct ConnectionCallbackParams_t {
00102         Handle_t      handle;
00103         Role_t        role;
00104         AddressType_t peerAddrType;
00105         Address_t     peerAddr;
00106         AddressType_t ownAddrType;
00107         Address_t     ownAddr;
00108         const ConnectionParams_t *connectionParams;
00109 
00110         ConnectionCallbackParams_t(Handle_t       handleIn,
00111                                    Role_t         roleIn,
00112                                    AddressType_t  peerAddrTypeIn,
00113                                    const uint8_t *peerAddrIn,
00114                                    AddressType_t  ownAddrTypeIn,
00115                                    const uint8_t *ownAddrIn,
00116                                    const ConnectionParams_t *connectionParamsIn) :
00117             handle(handleIn),
00118             role(roleIn),
00119             peerAddrType(peerAddrTypeIn),
00120             peerAddr(),
00121             ownAddrType(ownAddrTypeIn),
00122             ownAddr(),
00123             connectionParams(connectionParamsIn) {
00124             memcpy(peerAddr, peerAddrIn, ADDR_LEN);
00125             memcpy(ownAddr, ownAddrIn, ADDR_LEN);
00126         }
00127     };
00128 
00129     static const uint16_t UNIT_1_25_MS  = 1250; /**< Number of microseconds in 1.25 milliseconds. */
00130     static const uint16_t UNIT_0_625_MS = 625;  /**< Number of microseconds in 0.625 milliseconds. */
00131     static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) {
00132         return (durationInMillis * 1000) / UNIT_1_25_MS;
00133     }
00134     static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) {
00135         return (durationInMillis * 1000) / UNIT_0_625_MS;
00136     }
00137     static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits) {
00138         return (gapUnits * UNIT_0_625_MS) / 1000;
00139     }
00140 
00141     typedef void (*TimeoutEventCallback_t)(TimeoutSource_t source);
00142     typedef void (*ConnectionEventCallback_t)(const ConnectionCallbackParams_t *params);
00143     typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t);
00144     typedef void (*RadioNotificationEventCallback_t)(bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */
00145 
00146     /*
00147      * The following functions are meant to be overridden in the platform-specific sub-class.
00148      */
00149 public:
00150     /**
00151      * Set the BTLE MAC address and type. Please note that the address format is
00152      * LSB (least significant byte first). Please refer to Address_t.
00153      *
00154      * @return BLE_ERROR_NONE on success.
00155      */
00156     virtual ble_error_t setAddress(AddressType_t type, const Address_t address) {
00157         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00158     }
00159 
00160     /**
00161      * Fetch the BTLE MAC address and type.
00162      *
00163      * @return BLE_ERROR_NONE on success.
00164      */
00165     virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) {
00166         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00167     }
00168 
00169     /**
00170      * @return Minimum Advertising interval in milliseconds.
00171      */
00172     virtual uint16_t getMinAdvertisingInterval(void) const {
00173         return 0; /* default implementation; override this API if this capability is supported. */
00174     }
00175 
00176     /**
00177      * @return Minimum Advertising interval in milliseconds for non-connectible mode.
00178      */
00179     virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {
00180         return 0; /* default implementation; override this API if this capability is supported. */
00181     }
00182 
00183     /**
00184      * @return Maximum Advertising interval in milliseconds.
00185      */
00186     virtual uint16_t getMaxAdvertisingInterval(void) const {
00187         return 0xFFFF; /* default implementation; override this API if this capability is supported. */
00188     }
00189 
00190     virtual ble_error_t stopAdvertising(void) {
00191         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00192     }
00193 
00194     /**
00195      * Stop scanning. The current scanning parameters remain in effect.
00196      *
00197      * @retval BLE_ERROR_NONE if successfully stopped scanning procedure.
00198      */
00199     virtual ble_error_t stopScan() {
00200         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00201     }
00202 
00203     /**
00204      * Create a connection (GAP Link Establishment).
00205      *
00206      * @param peerAddr
00207      *          48-bit address, LSB format.
00208      * @param peerAddrType
00209      *          Address type of the peer.
00210      * @param connectionParams
00211      *         Connection parameters.
00212      * @param scanParams
00213      *          Paramters to be used while scanning for the peer.
00214      * @return  BLE_ERROR_NONE if connection establishment procedure is started
00215      *     successfully. The connectionCallback (if set) will be invoked upon
00216      *     a connection event.
00217      */
00218     virtual ble_error_t connect(const Address_t           peerAddr,
00219                                 Gap::AddressType_t        peerAddrType,
00220                                 const ConnectionParams_t *connectionParams,
00221                                 const GapScanningParams  *scanParams) {
00222         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00223     }
00224 
00225     /**
00226      * This call initiates the disconnection procedure, and its completion will
00227      * be communicated to the application with an invocation of the
00228      * disconnectionCallback.
00229      *
00230      * @param  reason
00231      *           The reason for disconnection to be sent back to the peer.
00232      */
00233     virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) {
00234         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00235     }
00236 
00237     /**
00238      * This call initiates the disconnection procedure, and its completion will
00239      * be communicated to the application with an invocation of the
00240      * disconnectionCallback.
00241      *
00242      * @param  reason
00243      *           The reason for disconnection to be sent back to the peer.
00244      *
00245      * @note: this version of disconnect() doesn't take a connection handle. It
00246      * will work reliably only for stacks which are limited to a single
00247      * connection. This API should be considered *deprecated* in favour of the
00248      * altertive which takes a connection handle. It will be dropped in the future.
00249      */
00250     virtual ble_error_t disconnect(DisconnectionReason_t reason) {
00251         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00252     }
00253 
00254     /**
00255      * Get the GAP peripheral preferred connection parameters. These are the
00256      * defaults that the peripheral would like to have in a connection. The
00257      * choice of the connection parameters is eventually up to the central.
00258      *
00259      * @param[out] params
00260      *               The structure where the parameters will be stored. Memory
00261      *               for this is owned by the caller.
00262      *
00263      * @return BLE_ERROR_NONE if the parameters were successfully filled into
00264      * the given structure pointed to by params.
00265      */
00266     virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) {
00267         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00268     }
00269 
00270     /**
00271      * Set the GAP peripheral preferred connection parameters. These are the
00272      * defaults that the peripheral would like to have in a connection. The
00273      * choice of the connection parameters is eventually up to the central.
00274      *
00275      * @param[in] params
00276      *               The structure containing the desired parameters.
00277      */
00278     virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) {
00279         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00280     }
00281 
00282     /**
00283      * Update connection parameters while in the peripheral role.
00284      * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for
00285      *          the central to perform the procedure.
00286      * @param[in] handle
00287      *              Connection Handle
00288      * @param[in] params
00289      *              Pointer to desired connection parameters. If NULL is provided on a peripheral role,
00290      *              the parameters in the PPCP characteristic of the GAP service will be used instead.
00291      */
00292     virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) {
00293         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00294     }
00295 
00296     /**
00297      * Set the device name characteristic in the GAP service.
00298      * @param[in] deviceName
00299      *              The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string.
00300      */
00301     virtual ble_error_t setDeviceName(const uint8_t *deviceName) {
00302         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00303     }
00304 
00305     /**
00306      * Get the value of the device name characteristic in the GAP service.
00307      * @param[out]    deviceName
00308      *                  Pointer to an empty buffer where the UTF-8 *non NULL-
00309      *                  terminated* string will be placed. Set this
00310      *                  value to NULL in order to obtain the deviceName-length
00311      *                  from the 'length' parameter.
00312      *
00313      * @param[in/out] lengthP
00314      *                  (on input) Length of the buffer pointed to by deviceName;
00315      *                  (on output) the complete device name length (without the
00316      *                     null terminator).
00317      *
00318      * @note If the device name is longer than the size of the supplied buffer,
00319      *     length will return the complete device name length, and not the
00320      *     number of bytes actually returned in deviceName. The application may
00321      *     use this information to retry with a suitable buffer size.
00322      */
00323     virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) {
00324         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00325     }
00326 
00327     /**
00328      * Set the appearance characteristic in the GAP service.
00329      * @param[in] appearance
00330      *              The new value for the device-appearance.
00331      */
00332     virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) {
00333         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00334     }
00335 
00336     /**
00337      * Get the appearance characteristic in the GAP service.
00338      * @param[out] appearance
00339      *               The new value for the device-appearance.
00340      */
00341     virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) {
00342         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00343     }
00344 
00345     /**
00346      * Set the radio's transmit power.
00347      * @param[in] txPower Radio transmit power in dBm.
00348      */
00349     virtual ble_error_t setTxPower(int8_t txPower) {
00350         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00351     }
00352 
00353     /**
00354      * Query the underlying stack for permitted arguments for setTxPower().
00355      *
00356      * @param[out] valueArrayPP
00357      *                 Out parameter to receive the immutable array of Tx values.
00358      * @param[out] countP
00359      *                 Out parameter to receive the array's size.
00360      */
00361     virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
00362         *countP = 0; /* default implementation; override this API if this capability is supported. */
00363     }
00364 
00365 protected:
00366     /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */
00367     virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) {
00368         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00369     }
00370 
00371     /*
00372      * APIs with non-virtual implementations.
00373      */
00374 public:
00375     /**
00376      * Returns the current GAP state of the device using a bitmask which
00377      * describes whether the device is advertising and/or connected.
00378      */
00379     GapState_t getState(void) const {
00380         return state;
00381     }
00382 
00383     /**
00384      * Set the GAP advertising mode to use for this device.
00385      */
00386     void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t  advType) {
00387         _advParams.setAdvertisingType(advType);
00388     }
00389 
00390     /**
00391      * @param[in] interval
00392      *              Advertising interval in units of milliseconds. Advertising
00393      *              is disabled if interval is 0. If interval is smaller than
00394      *              the minimum supported value, then the minimum supported
00395      *              value is used instead. This minimum value can be discovered
00396      *              using getMinAdvertisingInterval().
00397      *
00398      *              This field must be set to 0 if connectionMode is equal
00399      *              to ADV_CONNECTABLE_DIRECTED.
00400      *
00401      * @note: Decreasing this value will allow central devices to detect a
00402      * peripheral faster at the expense of more power being used by the radio
00403      * due to the higher data transmit rate.
00404      *
00405      * @note: This API is now *deprecated* and will be dropped in the future.
00406      * You should use the parallel API from Gap directly. A former call to
00407      * ble.setAdvertisingInterval(...) should now be achieved using
00408      * ble.gap().setAdvertisingInterval(...).
00409      *
00410      * @Note: [WARNING] This API previously used 0.625ms as the unit for its
00411      * 'interval' argument. That required an explicit conversion from
00412      * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is
00413      * no longer required as the new units are milliseconds. Any application
00414      * code depending on the old semantics would need to be updated accordingly.
00415      */
00416     void setAdvertisingInterval(uint16_t interval) {
00417         if (interval == 0) {
00418             stopAdvertising();
00419         } else if (interval < getMinAdvertisingInterval()) {
00420             interval = getMinAdvertisingInterval();
00421         }
00422         _advParams.setInterval(MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval));
00423     }
00424 
00425     /**
00426      * @param[in] timeout
00427      *              Advertising timeout (in seconds) between 0x1 and 0x3FFF (1
00428      *              and 16383). Use 0 to disable the advertising timeout.
00429      */
00430     void setAdvertisingTimeout(uint16_t timeout) {
00431         _advParams.setTimeout(timeout);
00432     }
00433 
00434     /**
00435      * Start advertising.
00436      */
00437     ble_error_t startAdvertising(void) {
00438         setAdvertisingData(); /* update the underlying stack */
00439         return startAdvertising(_advParams);
00440     }
00441 
00442     /**
00443      * Reset any advertising payload prepared from prior calls to
00444      * accumulateAdvertisingPayload(). This automatically propagates the re-
00445      * initialized adv payload to the underlying stack.
00446      *
00447      * Note: This should be followed by a call to setAdvertisingPayload() or
00448      * startAdvertising() before the update takes effect.
00449      */
00450     void clearAdvertisingPayload(void) {
00451         _advPayload.clear();
00452         setAdvertisingData();
00453     }
00454 
00455     /**
00456      * Accumulate an AD structure in the advertising payload. Please note that
00457      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00458      * as an additional 31 bytes if the advertising payload proves to be too
00459      * small.
00460      *
00461      * @param[in] flags
00462      *              The flags to be added. Please refer to
00463      *              GapAdvertisingData::Flags for valid flags. Multiple
00464      *              flags may be specified in combination.
00465      */
00466     ble_error_t accumulateAdvertisingPayload(uint8_t flags) {
00467         ble_error_t rc;
00468         if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) {
00469             return rc;
00470         }
00471 
00472         return setAdvertisingData();
00473     }
00474 
00475     /**
00476      * Accumulate an AD structure in the advertising payload. Please note that
00477      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00478      * as an additional 31 bytes if the advertising payload proves to be too
00479      * small.
00480      *
00481      * @param  app
00482      *         The appearance of the peripheral.
00483      */
00484     ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) {
00485         setAppearance(app);
00486 
00487         ble_error_t rc;
00488         if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) {
00489             return rc;
00490         }
00491 
00492         return setAdvertisingData();
00493     }
00494 
00495     /**
00496      * Accumulate an AD structure in the advertising payload. Please note that
00497      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00498      * as an additional 31 bytes if the advertising payload proves to be too
00499      * small.
00500      *
00501      * @param  app
00502      *         The max transmit power to be used by the controller. This is
00503      *         only a hint.
00504      */
00505     ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) {
00506         ble_error_t rc;
00507         if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) {
00508             return rc;
00509         }
00510 
00511         return setAdvertisingData();
00512     }
00513 
00514     /**
00515      * Accumulate a variable length byte-stream as an AD structure in the
00516      * advertising payload. Please note that the payload is limited to 31 bytes.
00517      * The SCAN_RESPONSE message may be used as an additional 31 bytes if the
00518      * advertising payload proves to be too small.
00519      *
00520      * @param  type The type which describes the variable length data.
00521      * @param  data data bytes.
00522      * @param  len  length of data.
00523      */
00524     ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
00525         if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
00526             setDeviceName(data);
00527         }
00528 
00529         ble_error_t rc;
00530         if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) {
00531             return rc;
00532         }
00533 
00534         return setAdvertisingData();
00535     }
00536 
00537     /**
00538      * Setup a particular, user-constructed advertisement payload for the
00539      * underlying stack. It would be uncommon for this API to be used directly;
00540      * there are other APIs to build an advertisement payload (see above).
00541      */
00542     ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) {
00543         _advPayload = payload;
00544         return setAdvertisingData();
00545     }
00546 
00547     /**
00548      * @return  Read back advertising data. Useful for storing and
00549      *          restoring payload.
00550      */
00551     const GapAdvertisingData &getAdvertisingPayload(void) const {
00552         return _advPayload;
00553     }
00554 
00555     /**
00556      * Accumulate a variable length byte-stream as an AD structure in the
00557      * scanResponse payload.
00558      *
00559      * @param[in] type The type which describes the variable length data.
00560      * @param[in] data data bytes.
00561      * @param[in] len  length of data.
00562      */
00563     ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
00564         ble_error_t rc;
00565         if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) {
00566             return rc;
00567         }
00568 
00569         return setAdvertisingData();
00570     }
00571 
00572     /**
00573      * Reset any scan response prepared from prior calls to
00574      * accumulateScanResponse().
00575      *
00576      * Note: This should be followed by a call to setAdvertisingPayload() or
00577      * startAdvertising() before the update takes effect.
00578      */
00579     void clearScanResponse(void) {
00580         _scanResponse.clear();
00581         setAdvertisingData();
00582     }
00583 
00584     /**
00585      * Setup parameters for GAP scanning--i.e. observer mode.
00586      * @param[in] interval
00587      *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00588      * @param[in] window
00589      *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00590      * @param[in] timeout
00591      *              Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout.
00592      * @param[in] activeScanning
00593      *              Set to True if active-scanning is required. This is used to fetch the
00594      *              scan response from a peer if possible.
00595      *
00596      * The scanning window divided by the interval determines the duty cycle for
00597      * scanning. For example, if the interval is 100ms and the window is 10ms,
00598      * then the controller will scan for 10 percent of the time. It is possible
00599      * to have the interval and window set to the same value. In this case,
00600      * scanning is continuous, with a change of scanning frequency once every
00601      * interval.
00602      *
00603      * Once the scanning parameters have been configured, scanning can be
00604      * enabled by using startScan().
00605      *
00606      * @Note: The scan interval and window are recommendations to the BLE stack.
00607      */
00608     ble_error_t setScanParams(uint16_t interval       = GapScanningParams::SCAN_INTERVAL_MAX,
00609                               uint16_t window         = GapScanningParams::SCAN_WINDOW_MAX,
00610                               uint16_t timeout        = 0,
00611                               bool     activeScanning = false) {
00612         ble_error_t rc;
00613         if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) &&
00614             ((rc = _scanningParams.setWindow(window))     == BLE_ERROR_NONE) &&
00615             ((rc = _scanningParams.setTimeout(timeout))   == BLE_ERROR_NONE)) {
00616             _scanningParams.setActiveScanning(activeScanning);
00617             return BLE_ERROR_NONE;
00618         }
00619 
00620         return rc;
00621     }
00622 
00623     /**
00624      * Setup the scanInterval parameter for GAP scanning--i.e. observer mode.
00625      * @param[in] interval
00626      *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00627      *
00628      * The scanning window divided by the interval determines the duty cycle for
00629      * scanning. For example, if the interval is 100ms and the window is 10ms,
00630      * then the controller will scan for 10 percent of the time. It is possible
00631      * to have the interval and window set to the same value. In this case,
00632      * scanning is continuous, with a change of scanning frequency once every
00633      * interval.
00634      *
00635      * Once the scanning parameters have been configured, scanning can be
00636      * enabled by using startScan().
00637      */
00638     ble_error_t setScanInterval(uint16_t interval) {
00639         return _scanningParams.setInterval(interval);
00640     }
00641 
00642     /**
00643      * Setup the scanWindow parameter for GAP scanning--i.e. observer mode.
00644      * @param[in] window
00645      *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00646      *
00647      * The scanning window divided by the interval determines the duty cycle for
00648      * scanning. For example, if the interval is 100ms and the window is 10ms,
00649      * then the controller will scan for 10 percent of the time. It is possible
00650      * to have the interval and window set to the same value. In this case,
00651      * scanning is continuous, with a change of scanning frequency once every
00652      * interval.
00653      *
00654      * Once the scanning parameters have been configured, scanning can be
00655      * enabled by using startScan().
00656      */
00657     ble_error_t setScanWindow(uint16_t window) {
00658         return _scanningParams.setWindow(window);
00659     }
00660 
00661     /**
00662      * Setup parameters for GAP scanning--i.e. observer mode.
00663      * @param[in] timeout
00664      *              Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout.
00665      *
00666      * Once the scanning parameters have been configured, scanning can be
00667      * enabled by using startScan().
00668      */
00669     ble_error_t setScanTimeout(uint16_t timeout) {
00670         return _scanningParams.setTimeout(timeout);
00671     }
00672 
00673     /**
00674      * Setup parameters for GAP scanning--i.e. observer mode.
00675      * @param[in] activeScanning
00676      *              Set to True if active-scanning is required. This is used to fetch the
00677      *              scan response from a peer if possible.
00678      *
00679      * Once the scanning parameters have been configured, scanning can be
00680      * enabled by using startScan().
00681      */
00682     void setActiveScanning(bool activeScanning) {
00683         _scanningParams.setActiveScanning(activeScanning);
00684     }
00685 
00686     /**
00687      * Start scanning (Observer Procedure) based on the parameters currently in
00688      * effect.
00689      *
00690      * @param[in] callback
00691      *              The application specific callback to be invoked upon
00692      *              receiving every advertisement report. This can be passed in
00693      *              as NULL, in which case scanning may not be enabled at all.
00694      */
00695     ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) {
00696         ble_error_t err = BLE_ERROR_NONE;
00697         if (callback) {
00698             if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
00699                 onAdvertisementReport.attach(callback);
00700             }
00701         }
00702 
00703         return err;
00704     }
00705 
00706     /**
00707      * Same as above, but this takes an (object, method) pair for a callback.
00708      */
00709     template<typename T>
00710     ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) {
00711         ble_error_t err = BLE_ERROR_NONE;
00712         if (object && callbackMember) {
00713             if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
00714                 onAdvertisementReport.attach(object, callbackMember);
00715             }
00716         }
00717 
00718         return err;
00719     }
00720 
00721 private:
00722     ble_error_t setAdvertisingData(void) {
00723         return setAdvertisingData(_advPayload, _scanResponse);
00724     }
00725 
00726 private:
00727     virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0;
00728     virtual ble_error_t startAdvertising(const GapAdvertisingParams &)                             = 0;
00729 
00730 public:
00731     /**
00732      * Accessors to read back currently active advertising params.
00733      */
00734     GapAdvertisingParams &getAdvertisingParams(void) {
00735         return _advParams;
00736     }
00737     const GapAdvertisingParams &getAdvertisingParams(void) const {
00738         return _advParams;
00739     }
00740 
00741     /**
00742      * Setup a particular, user-constructed set of advertisement parameters for
00743      * the underlying stack. It would be uncommon for this API to be used
00744      * directly; there are other APIs to tweak advertisement parameters
00745      * individually.
00746      */
00747     void setAdvertisingParams(const GapAdvertisingParams &newParams) {
00748         _advParams = newParams;
00749     }
00750 
00751     /* Event callback handlers. */
00752 public:
00753     /**
00754      * Setup a callback for timeout events. Refer to TimeoutSource_t for
00755      * possible event types.
00756      */
00757     void onTimeout(TimeoutEventCallback_t callback) {timeoutCallback = callback;}
00758 
00759     /**
00760      * Setup a callback for connection events. Refer to ConnectionEventCallback_t.
00761      */
00762     void onConnection(ConnectionEventCallback_t callback) {connectionCallback = callback;}
00763 
00764     /**
00765      * Set the application callback for disconnection events.
00766      * @param callback
00767      *        Pointer to the unique callback.
00768      */
00769     void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallback = callback;}
00770 
00771     /**
00772      * Append to a chain of callbacks to be invoked upon disconnection; these
00773      * callbacks receive no context and are therefore different from the
00774      * disconnectionCallback callback.
00775      * @param callback
00776      *        function pointer to be invoked upon disconnection; receives no context.
00777      */
00778     template<typename T>
00779     void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) {disconnectionCallChain.add(tptr, mptr);}
00780 
00781     /**
00782      * Set the application callback for radio-notification events.
00783      *
00784      * Radio Notification is a feature that enables ACTIVE and INACTIVE
00785      * (nACTIVE) signals from the stack that notify the application when the
00786      * radio is in use. The signal is sent using software interrupt.
00787      *
00788      * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE
00789      * signal is sent at the end of the Radio Event. These signals can be used
00790      * by the application programmer to synchronize application logic with radio
00791      * activity. For example, the ACTIVE signal can be used to shut off external
00792      * devices to manage peak current drawn during periods when the radio is on,
00793      * or to trigger sensor data collection for transmission in the Radio Event.
00794      *
00795      * @param callback
00796      *          The application handler to be invoked in response to a radio
00797      *          ACTIVE/INACTIVE event.
00798      */
00799     virtual void onRadioNotification(RadioNotificationEventCallback_t callback) {radioNotificationCallback = callback;}
00800 
00801 protected:
00802     Gap() :
00803         _advParams(),
00804         _advPayload(),
00805         _scanningParams(),
00806         _scanResponse(),
00807         state(),
00808         timeoutCallback(NULL),
00809         connectionCallback(NULL),
00810         disconnectionCallback(NULL),
00811         radioNotificationCallback(),
00812         onAdvertisementReport(),
00813         disconnectionCallChain() {
00814         _advPayload.clear();
00815         _scanResponse.clear();
00816     }
00817 
00818     /* Entry points for the underlying stack to report events back to the user. */
00819 public:
00820     void processConnectionEvent(Handle_t                  handle,
00821                                 Role_t                    role,
00822                                 AddressType_t             peerAddrType,
00823                                 const Address_t           peerAddr,
00824                                 AddressType_t             ownAddrType,
00825                                 const Address_t           ownAddr,
00826                                 const ConnectionParams_t *connectionParams) {
00827         state.connected = 1;
00828         if (connectionCallback) {
00829             ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams);
00830             connectionCallback(&callbackParams);
00831         }
00832     }
00833 
00834     void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) {
00835         state.connected = 0;
00836         if (disconnectionCallback) {
00837             disconnectionCallback(handle, reason);
00838         }
00839         disconnectionCallChain.call();
00840     }
00841 
00842     void processAdvertisementReport(const Address_t    peerAddr,
00843                                     int8_t             rssi,
00844                                     bool               isScanResponse,
00845                                     GapAdvertisingParams::AdvertisingType_t   type,
00846                                     uint8_t            advertisingDataLen,
00847                                     const uint8_t     *advertisingData) {
00848         AdvertisementCallbackParams_t params;
00849         memcpy(params.peerAddr, peerAddr, ADDR_LEN);
00850         params.rssi               = rssi;
00851         params.isScanResponse     = isScanResponse;
00852         params.type               = type;
00853         params.advertisingDataLen = advertisingDataLen;
00854         params.advertisingData    = advertisingData;
00855         onAdvertisementReport.call(&params);
00856     }
00857 
00858     void processTimeoutEvent(TimeoutSource_t source) {
00859         if (timeoutCallback) {
00860             timeoutCallback(source);
00861         }
00862     }
00863 
00864 protected:
00865     GapAdvertisingParams             _advParams;
00866     GapAdvertisingData               _advPayload;
00867     GapScanningParams                _scanningParams;
00868     GapAdvertisingData               _scanResponse;
00869 
00870     GapState_t                       state;
00871 
00872 protected:
00873     TimeoutEventCallback_t           timeoutCallback;
00874     ConnectionEventCallback_t        connectionCallback;
00875     DisconnectionEventCallback_t     disconnectionCallback;
00876     RadioNotificationEventCallback_t radioNotificationCallback;
00877     AdvertisementReportCallback_t    onAdvertisementReport;
00878     CallChain                        disconnectionCallChain;
00879 
00880 private:
00881     /* disallow copy and assignment */
00882     Gap(const Gap &);
00883     Gap& operator=(const Gap &);
00884 };
00885 
00886 #endif // ifndef __GAP_H__