Changed URIBeaconConfigService.h to work with ST board

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 FunctionPointerWithContext<bool>  RadioNotificationEventCallback_t;
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         /* avoid compiler warnings about unused variables */
00158         (void)type;
00159         (void)address;
00160 
00161         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00162     }
00163 
00164     /**
00165      * Fetch the BTLE MAC address and type.
00166      *
00167      * @return BLE_ERROR_NONE on success.
00168      */
00169     virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) {
00170         /* avoid compiler warnings about unused variables */
00171         (void)typeP;
00172         (void)address;
00173 
00174         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00175     }
00176 
00177     /**
00178      * @return Minimum Advertising interval in milliseconds.
00179      */
00180     virtual uint16_t getMinAdvertisingInterval(void) const {
00181         return 0; /* Requesting action from porter(s): override this API if this capability is supported. */
00182     }
00183 
00184     /**
00185      * @return Minimum Advertising interval in milliseconds for non-connectible mode.
00186      */
00187     virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {
00188         return 0; /* Requesting action from porter(s): override this API if this capability is supported. */
00189     }
00190 
00191     /**
00192      * @return Maximum Advertising interval in milliseconds.
00193      */
00194     virtual uint16_t getMaxAdvertisingInterval(void) const {
00195         return 0xFFFF; /* Requesting action from porter(s): override this API if this capability is supported. */
00196     }
00197 
00198     virtual ble_error_t stopAdvertising(void) {
00199         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00200     }
00201 
00202     /**
00203      * Stop scanning. The current scanning parameters remain in effect.
00204      *
00205      * @retval BLE_ERROR_NONE if successfully stopped scanning procedure.
00206      */
00207     virtual ble_error_t stopScan() {
00208         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00209     }
00210 
00211     /**
00212      * Create a connection (GAP Link Establishment).
00213      *
00214      * @param peerAddr
00215      *          48-bit address, LSB format.
00216      * @param peerAddrType
00217      *          Address type of the peer.
00218      * @param connectionParams
00219      *         Connection parameters.
00220      * @param scanParams
00221      *          Paramters to be used while scanning for the peer.
00222      * @return  BLE_ERROR_NONE if connection establishment procedure is started
00223      *     successfully. The connectionCallback (if set) will be invoked upon
00224      *     a connection event.
00225      */
00226     virtual ble_error_t connect(const Address_t           peerAddr,
00227                                 Gap::AddressType_t        peerAddrType,
00228                                 const ConnectionParams_t *connectionParams,
00229                                 const GapScanningParams  *scanParams) {
00230         /* avoid compiler warnings about unused variables */
00231         (void)peerAddr;
00232         (void)peerAddrType;
00233         (void)connectionParams;
00234         (void)scanParams;
00235 
00236         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00237     }
00238 
00239     /**
00240      * This call initiates the disconnection procedure, and its completion will
00241      * be communicated to the application with an invocation of the
00242      * disconnectionCallback.
00243      *
00244      * @param  reason
00245      *           The reason for disconnection to be sent back to the peer.
00246      */
00247     virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) {
00248         /* avoid compiler warnings about unused variables */
00249         (void)connectionHandle;
00250         (void)reason;
00251 
00252         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00253     }
00254 
00255     /**
00256      * This call initiates the disconnection procedure, and its completion will
00257      * be communicated to the application with an invocation of the
00258      * disconnectionCallback.
00259      *
00260      * @param  reason
00261      *           The reason for disconnection to be sent back to the peer.
00262      *
00263      * @note: this version of disconnect() doesn't take a connection handle. It
00264      * will work reliably only for stacks which are limited to a single
00265      * connection. This API should be considered *deprecated* in favour of the
00266      * altertive which takes a connection handle. It will be dropped in the future.
00267      */
00268     virtual ble_error_t disconnect(DisconnectionReason_t reason) {
00269         /* avoid compiler warnings about unused variables */
00270         (void)reason;
00271 
00272         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00273     }
00274 
00275     /**
00276      * Get the GAP peripheral preferred connection parameters. These are the
00277      * defaults that the peripheral would like to have in a connection. The
00278      * choice of the connection parameters is eventually up to the central.
00279      *
00280      * @param[out] params
00281      *               The structure where the parameters will be stored. Memory
00282      *               for this is owned by the caller.
00283      *
00284      * @return BLE_ERROR_NONE if the parameters were successfully filled into
00285      * the given structure pointed to by params.
00286      */
00287     virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) {
00288         /* avoid compiler warnings about unused variables */
00289         (void)params;
00290 
00291         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00292     }
00293 
00294     /**
00295      * Set the GAP peripheral preferred connection parameters. These are the
00296      * defaults that the peripheral would like to have in a connection. The
00297      * choice of the connection parameters is eventually up to the central.
00298      *
00299      * @param[in] params
00300      *               The structure containing the desired parameters.
00301      */
00302     virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) {
00303         /* avoid compiler warnings about unused variables */
00304         (void)params;
00305 
00306         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00307     }
00308 
00309     /**
00310      * Update connection parameters while in the peripheral role.
00311      * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for
00312      *          the central to perform the procedure.
00313      * @param[in] handle
00314      *              Connection Handle
00315      * @param[in] params
00316      *              Pointer to desired connection parameters. If NULL is provided on a peripheral role,
00317      *              the parameters in the PPCP characteristic of the GAP service will be used instead.
00318      */
00319     virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) {
00320         /* avoid compiler warnings about unused variables */
00321         (void)handle;
00322         (void)params;
00323 
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 device name characteristic in the GAP service.
00329      * @param[in] deviceName
00330      *              The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string.
00331      */
00332     virtual ble_error_t setDeviceName(const uint8_t *deviceName) {
00333         /* avoid compiler warnings about unused variables */
00334         (void)deviceName;
00335 
00336         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00337     }
00338 
00339     /**
00340      * Get the value of the device name characteristic in the GAP service.
00341      * @param[out]    deviceName
00342      *                  Pointer to an empty buffer where the UTF-8 *non NULL-
00343      *                  terminated* string will be placed. Set this
00344      *                  value to NULL in order to obtain the deviceName-length
00345      *                  from the 'length' parameter.
00346      *
00347      * @param[in/out] lengthP
00348      *                  (on input) Length of the buffer pointed to by deviceName;
00349      *                  (on output) the complete device name length (without the
00350      *                     null terminator).
00351      *
00352      * @note If the device name is longer than the size of the supplied buffer,
00353      *     length will return the complete device name length, and not the
00354      *     number of bytes actually returned in deviceName. The application may
00355      *     use this information to retry with a suitable buffer size.
00356      */
00357     virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) {
00358         /* avoid compiler warnings about unused variables */
00359         (void)deviceName;
00360         (void)lengthP;
00361 
00362         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00363     }
00364 
00365     /**
00366      * Set the appearance characteristic in the GAP service.
00367      * @param[in] appearance
00368      *              The new value for the device-appearance.
00369      */
00370     virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) {
00371         /* avoid compiler warnings about unused variables */
00372         (void)appearance;
00373 
00374         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00375     }
00376 
00377     /**
00378      * Get the appearance characteristic in the GAP service.
00379      * @param[out] appearance
00380      *               The new value for the device-appearance.
00381      */
00382     virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) {
00383         /* avoid compiler warnings about unused variables */
00384         (void)appearanceP;
00385 
00386         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00387     }
00388 
00389     /**
00390      * Set the radio's transmit power.
00391      * @param[in] txPower Radio transmit power in dBm.
00392      */
00393     virtual ble_error_t setTxPower(int8_t txPower) {
00394         /* avoid compiler warnings about unused variables */
00395         (void)txPower;
00396 
00397         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00398     }
00399 
00400     /**
00401      * Query the underlying stack for permitted arguments for setTxPower().
00402      *
00403      * @param[out] valueArrayPP
00404      *                 Out parameter to receive the immutable array of Tx values.
00405      * @param[out] countP
00406      *                 Out parameter to receive the array's size.
00407      */
00408     virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
00409         /* avoid compiler warnings about unused variables */
00410         (void)valueArrayPP;
00411         (void)countP;
00412 
00413         *countP = 0; /* Requesting action from porter(s): override this API if this capability is supported. */
00414     }
00415 
00416 protected:
00417     /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */
00418     virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) {
00419         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00420     }
00421 
00422     /*
00423      * APIs with non-virtual implementations.
00424      */
00425 public:
00426     /**
00427      * Returns the current GAP state of the device using a bitmask which
00428      * describes whether the device is advertising and/or connected.
00429      */
00430     GapState_t getState(void) const {
00431         return state;
00432     }
00433 
00434     /**
00435      * Set the GAP advertising mode to use for this device.
00436      */
00437     void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t  advType) {
00438         _advParams.setAdvertisingType(advType);
00439     }
00440 
00441     /**
00442      * @param[in] interval
00443      *              Advertising interval in units of milliseconds. Advertising
00444      *              is disabled if interval is 0. If interval is smaller than
00445      *              the minimum supported value, then the minimum supported
00446      *              value is used instead. This minimum value can be discovered
00447      *              using getMinAdvertisingInterval().
00448      *
00449      *              This field must be set to 0 if connectionMode is equal
00450      *              to ADV_CONNECTABLE_DIRECTED.
00451      *
00452      * @note: Decreasing this value will allow central devices to detect a
00453      * peripheral faster at the expense of more power being used by the radio
00454      * due to the higher data transmit rate.
00455      *
00456      * @note: This API is now *deprecated* and will be dropped in the future.
00457      * You should use the parallel API from Gap directly. A former call to
00458      * ble.setAdvertisingInterval(...) should now be achieved using
00459      * ble.gap().setAdvertisingInterval(...).
00460      *
00461      * @Note: [WARNING] This API previously used 0.625ms as the unit for its
00462      * 'interval' argument. That required an explicit conversion from
00463      * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is
00464      * no longer required as the new units are milliseconds. Any application
00465      * code depending on the old semantics would need to be updated accordingly.
00466      */
00467     void setAdvertisingInterval(uint16_t interval) {
00468         if (interval == 0) {
00469             stopAdvertising();
00470         } else if (interval < getMinAdvertisingInterval()) {
00471             interval = getMinAdvertisingInterval();
00472         }
00473         _advParams.setInterval(MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval));
00474     }
00475 
00476     /**
00477      * @param[in] timeout
00478      *              Advertising timeout (in seconds) between 0x1 and 0x3FFF (1
00479      *              and 16383). Use 0 to disable the advertising timeout.
00480      */
00481     void setAdvertisingTimeout(uint16_t timeout) {
00482         _advParams.setTimeout(timeout);
00483     }
00484 
00485     /**
00486      * Start advertising.
00487      */
00488     ble_error_t startAdvertising(void) {
00489         setAdvertisingData(); /* update the underlying stack */
00490         return startAdvertising(_advParams);
00491     }
00492 
00493     /**
00494      * Reset any advertising payload prepared from prior calls to
00495      * accumulateAdvertisingPayload(). This automatically propagates the re-
00496      * initialized adv payload to the underlying stack.
00497      *
00498      * Note: This should be followed by a call to setAdvertisingPayload() or
00499      * startAdvertising() before the update takes effect.
00500      */
00501     void clearAdvertisingPayload(void) {
00502         _advPayload.clear();
00503         setAdvertisingData();
00504     }
00505 
00506     /**
00507      * Accumulate an AD structure in the advertising payload. Please note that
00508      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00509      * as an additional 31 bytes if the advertising payload proves to be too
00510      * small.
00511      *
00512      * @param[in] flags
00513      *              The flags to be added. Please refer to
00514      *              GapAdvertisingData::Flags for valid flags. Multiple
00515      *              flags may be specified in combination.
00516      */
00517     ble_error_t accumulateAdvertisingPayload(uint8_t flags) {
00518         ble_error_t rc;
00519         if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) {
00520             return rc;
00521         }
00522 
00523         return setAdvertisingData();
00524     }
00525 
00526     /**
00527      * Accumulate an AD structure in the advertising payload. Please note that
00528      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00529      * as an additional 31 bytes if the advertising payload proves to be too
00530      * small.
00531      *
00532      * @param  app
00533      *         The appearance of the peripheral.
00534      */
00535     ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) {
00536         setAppearance(app);
00537 
00538         ble_error_t rc;
00539         if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) {
00540             return rc;
00541         }
00542 
00543         return setAdvertisingData();
00544     }
00545 
00546     /**
00547      * Accumulate an AD structure in the advertising payload. Please note that
00548      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00549      * as an additional 31 bytes if the advertising payload proves to be too
00550      * small.
00551      *
00552      * @param  app
00553      *         The max transmit power to be used by the controller. This is
00554      *         only a hint.
00555      */
00556     ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) {
00557         ble_error_t rc;
00558         if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) {
00559             return rc;
00560         }
00561 
00562         return setAdvertisingData();
00563     }
00564 
00565     /**
00566      * Accumulate a variable length byte-stream as an AD structure in the
00567      * advertising payload. Please note that the payload is limited to 31 bytes.
00568      * The SCAN_RESPONSE message may be used as an additional 31 bytes if the
00569      * advertising payload proves to be too small.
00570      *
00571      * @param  type The type which describes the variable length data.
00572      * @param  data data bytes.
00573      * @param  len  length of data.
00574      */
00575     ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
00576         if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
00577             setDeviceName(data);
00578         }
00579 
00580         ble_error_t rc;
00581         if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) {
00582             return rc;
00583         }
00584 
00585         return setAdvertisingData();
00586     }
00587 
00588     /**
00589      * Setup a particular, user-constructed advertisement payload for the
00590      * underlying stack. It would be uncommon for this API to be used directly;
00591      * there are other APIs to build an advertisement payload (see above).
00592      */
00593     ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) {
00594         _advPayload = payload;
00595         return setAdvertisingData();
00596     }
00597 
00598     /**
00599      * @return  Read back advertising data. Useful for storing and
00600      *          restoring payload.
00601      */
00602     const GapAdvertisingData &getAdvertisingPayload(void) const {
00603         return _advPayload;
00604     }
00605 
00606     /**
00607      * Accumulate a variable length byte-stream as an AD structure in the
00608      * scanResponse payload.
00609      *
00610      * @param[in] type The type which describes the variable length data.
00611      * @param[in] data data bytes.
00612      * @param[in] len  length of data.
00613      */
00614     ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
00615         ble_error_t rc;
00616         if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) {
00617             return rc;
00618         }
00619 
00620         return setAdvertisingData();
00621     }
00622 
00623     /**
00624      * Reset any scan response prepared from prior calls to
00625      * accumulateScanResponse().
00626      *
00627      * Note: This should be followed by a call to setAdvertisingPayload() or
00628      * startAdvertising() before the update takes effect.
00629      */
00630     void clearScanResponse(void) {
00631         _scanResponse.clear();
00632         setAdvertisingData();
00633     }
00634 
00635     /**
00636      * Setup parameters for GAP scanning--i.e. observer mode.
00637      * @param[in] interval
00638      *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00639      * @param[in] window
00640      *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00641      * @param[in] timeout
00642      *              Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout.
00643      * @param[in] activeScanning
00644      *              Set to True if active-scanning is required. This is used to fetch the
00645      *              scan response from a peer if possible.
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      * @Note: The scan interval and window are recommendations to the BLE stack.
00658      */
00659     ble_error_t setScanParams(uint16_t interval       = GapScanningParams::SCAN_INTERVAL_MAX,
00660                               uint16_t window         = GapScanningParams::SCAN_WINDOW_MAX,
00661                               uint16_t timeout        = 0,
00662                               bool     activeScanning = false) {
00663         ble_error_t rc;
00664         if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) &&
00665             ((rc = _scanningParams.setWindow(window))     == BLE_ERROR_NONE) &&
00666             ((rc = _scanningParams.setTimeout(timeout))   == BLE_ERROR_NONE)) {
00667             _scanningParams.setActiveScanning(activeScanning);
00668             return BLE_ERROR_NONE;
00669         }
00670 
00671         return rc;
00672     }
00673 
00674     /**
00675      * Setup the scanInterval parameter for GAP scanning--i.e. observer mode.
00676      * @param[in] interval
00677      *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00678      *
00679      * The scanning window divided by the interval determines the duty cycle for
00680      * scanning. For example, if the interval is 100ms and the window is 10ms,
00681      * then the controller will scan for 10 percent of the time. It is possible
00682      * to have the interval and window set to the same value. In this case,
00683      * scanning is continuous, with a change of scanning frequency once every
00684      * interval.
00685      *
00686      * Once the scanning parameters have been configured, scanning can be
00687      * enabled by using startScan().
00688      */
00689     ble_error_t setScanInterval(uint16_t interval) {
00690         return _scanningParams.setInterval(interval);
00691     }
00692 
00693     /**
00694      * Setup the scanWindow parameter for GAP scanning--i.e. observer mode.
00695      * @param[in] window
00696      *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
00697      *
00698      * The scanning window divided by the interval determines the duty cycle for
00699      * scanning. For example, if the interval is 100ms and the window is 10ms,
00700      * then the controller will scan for 10 percent of the time. It is possible
00701      * to have the interval and window set to the same value. In this case,
00702      * scanning is continuous, with a change of scanning frequency once every
00703      * interval.
00704      *
00705      * Once the scanning parameters have been configured, scanning can be
00706      * enabled by using startScan().
00707      */
00708     ble_error_t setScanWindow(uint16_t window) {
00709         return _scanningParams.setWindow(window);
00710     }
00711 
00712     /**
00713      * Setup parameters for GAP scanning--i.e. observer mode.
00714      * @param[in] timeout
00715      *              Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout.
00716      *
00717      * Once the scanning parameters have been configured, scanning can be
00718      * enabled by using startScan().
00719      */
00720     ble_error_t setScanTimeout(uint16_t timeout) {
00721         return _scanningParams.setTimeout(timeout);
00722     }
00723 
00724     /**
00725      * Setup parameters for GAP scanning--i.e. observer mode.
00726      * @param[in] activeScanning
00727      *              Set to True if active-scanning is required. This is used to fetch the
00728      *              scan response from a peer if possible.
00729      *
00730      * Once the scanning parameters have been configured, scanning can be
00731      * enabled by using startScan().
00732      */
00733     void setActiveScanning(bool activeScanning) {
00734         _scanningParams.setActiveScanning(activeScanning);
00735     }
00736 
00737     /**
00738      * Start scanning (Observer Procedure) based on the parameters currently in
00739      * effect.
00740      *
00741      * @param[in] callback
00742      *              The application specific callback to be invoked upon
00743      *              receiving every advertisement report. This can be passed in
00744      *              as NULL, in which case scanning may not be enabled at all.
00745      */
00746     ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) {
00747         ble_error_t err = BLE_ERROR_NONE;
00748         if (callback) {
00749             if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
00750                 onAdvertisementReport.attach(callback);
00751             }
00752         }
00753 
00754         return err;
00755     }
00756 
00757     /**
00758      * Same as above, but this takes an (object, method) pair for a callback.
00759      */
00760     template<typename T>
00761     ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) {
00762         ble_error_t err = BLE_ERROR_NONE;
00763         if (object && callbackMember) {
00764             if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
00765                 onAdvertisementReport.attach(object, callbackMember);
00766             }
00767         }
00768 
00769         return err;
00770     }
00771 
00772     /**
00773      * Initialize radio-notification events to be generated from the stack.
00774      * This API doesn't need to be called directly;
00775      *
00776      * Radio Notification is a feature that enables ACTIVE and INACTIVE
00777      * (nACTIVE) signals from the stack that notify the application when the
00778      * radio is in use.
00779      *
00780      * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE
00781      * signal is sent at the end of the Radio Event. These signals can be used
00782      * by the application programmer to synchronize application logic with radio
00783      * activity. For example, the ACTIVE signal can be used to shut off external
00784      * devices to manage peak current drawn during periods when the radio is on,
00785      * or to trigger sensor data collection for transmission in the Radio Event.
00786      *
00787      * @return BLE_ERROR_NONE on successful initialization, otherwise an error code.
00788      */
00789     virtual ble_error_t initRadioNotification(void) {
00790         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00791     }
00792 
00793 private:
00794     ble_error_t setAdvertisingData(void) {
00795         return setAdvertisingData(_advPayload, _scanResponse);
00796     }
00797 
00798 private:
00799     virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0;
00800     virtual ble_error_t startAdvertising(const GapAdvertisingParams &)                             = 0;
00801 
00802 public:
00803     /**
00804      * Accessors to read back currently active advertising params.
00805      */
00806     GapAdvertisingParams &getAdvertisingParams(void) {
00807         return _advParams;
00808     }
00809     const GapAdvertisingParams &getAdvertisingParams(void) const {
00810         return _advParams;
00811     }
00812 
00813     /**
00814      * Setup a particular, user-constructed set of advertisement parameters for
00815      * the underlying stack. It would be uncommon for this API to be used
00816      * directly; there are other APIs to tweak advertisement parameters
00817      * individually.
00818      */
00819     void setAdvertisingParams(const GapAdvertisingParams &newParams) {
00820         _advParams = newParams;
00821     }
00822 
00823     /* Event callback handlers. */
00824 public:
00825     /**
00826      * Setup a callback for timeout events. Refer to TimeoutSource_t for
00827      * possible event types.
00828      */
00829     void onTimeout(TimeoutEventCallback_t callback) {timeoutCallback = callback;}
00830 
00831     /**
00832      * Setup a callback for connection events. Refer to ConnectionEventCallback_t.
00833      */
00834     void onConnection(ConnectionEventCallback_t callback) {connectionCallback = callback;}
00835 
00836     /**
00837      * Set the application callback for disconnection events.
00838      * @param callback
00839      *        Pointer to the unique callback.
00840      */
00841     void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallback = callback;}
00842 
00843     /**
00844      * Append to a chain of callbacks to be invoked upon disconnection; these
00845      * callbacks receive no context and are therefore different from the
00846      * disconnectionCallback callback.
00847      * @param callback
00848      *        function pointer to be invoked upon disconnection; receives no context.
00849      */
00850     template<typename T>
00851     void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) {disconnectionCallChain.add(tptr, mptr);}
00852 
00853     /**
00854      * Set the application callback for radio-notification events.
00855      *
00856      * Radio Notification is a feature that enables ACTIVE and INACTIVE
00857      * (nACTIVE) signals from the stack that notify the application when the
00858      * radio is in use.
00859      *
00860      * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE
00861      * signal is sent at the end of the Radio Event. These signals can be used
00862      * by the application programmer to synchronize application logic with radio
00863      * activity. For example, the ACTIVE signal can be used to shut off external
00864      * devices to manage peak current drawn during periods when the radio is on,
00865      * or to trigger sensor data collection for transmission in the Radio Event.
00866      *
00867      * @param callback
00868      *          The application handler to be invoked in response to a radio
00869      *          ACTIVE/INACTIVE event.
00870      *
00871      * or in the other version:
00872      *
00873      * @param tptr
00874      *          Pointer to the object of a class defining the member callback
00875      *          function (mptr).
00876      * @param mptr
00877      *          The member callback (within the context of an object) to be
00878      *          invoked in response to a radio ACTIVE/INACTIVE event.
00879      */
00880     void onRadioNotification(void (*callback)(bool param)) {
00881         radioNotificationCallback.attach(callback);
00882         initRadioNotification();
00883     }
00884     template <typename T>
00885     void onRadioNotification(T *tptr, void (T::*mptr)(bool)) {
00886         radioNotificationCallback.attach(tptr, mptr);
00887         initRadioNotification();
00888     }
00889 
00890 protected:
00891     Gap() :
00892         _advParams(),
00893         _advPayload(),
00894         _scanningParams(),
00895         _scanResponse(),
00896         state(),
00897         timeoutCallback(NULL),
00898         connectionCallback(NULL),
00899         disconnectionCallback(NULL),
00900         radioNotificationCallback(),
00901         onAdvertisementReport(),
00902         disconnectionCallChain() {
00903         _advPayload.clear();
00904         _scanResponse.clear();
00905     }
00906 
00907     /* Entry points for the underlying stack to report events back to the user. */
00908 public:
00909     void processConnectionEvent(Handle_t                  handle,
00910                                 Role_t                    role,
00911                                 AddressType_t             peerAddrType,
00912                                 const Address_t           peerAddr,
00913                                 AddressType_t             ownAddrType,
00914                                 const Address_t           ownAddr,
00915                                 const ConnectionParams_t *connectionParams) {
00916         state.connected = 1;
00917         if (connectionCallback) {
00918             ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams);
00919             connectionCallback(&callbackParams);
00920         }
00921     }
00922 
00923     void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) {
00924         state.connected = 0;
00925         if (disconnectionCallback) {
00926             disconnectionCallback(handle, reason);
00927         }
00928         disconnectionCallChain.call();
00929     }
00930 
00931     void processAdvertisementReport(const Address_t    peerAddr,
00932                                     int8_t             rssi,
00933                                     bool               isScanResponse,
00934                                     GapAdvertisingParams::AdvertisingType_t   type,
00935                                     uint8_t            advertisingDataLen,
00936                                     const uint8_t     *advertisingData) {
00937         AdvertisementCallbackParams_t params;
00938         memcpy(params.peerAddr, peerAddr, ADDR_LEN);
00939         params.rssi               = rssi;
00940         params.isScanResponse     = isScanResponse;
00941         params.type               = type;
00942         params.advertisingDataLen = advertisingDataLen;
00943         params.advertisingData    = advertisingData;
00944         onAdvertisementReport.call(&params);
00945     }
00946 
00947     void processTimeoutEvent(TimeoutSource_t source) {
00948         if (timeoutCallback) {
00949             timeoutCallback(source);
00950         }
00951     }
00952 
00953 protected:
00954     GapAdvertisingParams             _advParams;
00955     GapAdvertisingData               _advPayload;
00956     GapScanningParams                _scanningParams;
00957     GapAdvertisingData               _scanResponse;
00958 
00959     GapState_t                       state;
00960 
00961 protected:
00962     TimeoutEventCallback_t           timeoutCallback;
00963     ConnectionEventCallback_t        connectionCallback;
00964     DisconnectionEventCallback_t     disconnectionCallback;
00965     RadioNotificationEventCallback_t radioNotificationCallback;
00966     AdvertisementReportCallback_t    onAdvertisementReport;
00967     CallChain                        disconnectionCallChain;
00968 
00969 private:
00970     /* disallow copy and assignment */
00971     Gap(const Gap &);
00972     Gap& operator=(const Gap &);
00973 };
00974 
00975 #endif // ifndef __GAP_H__