Added an EddystoneURLConfigService in addition to UriBeaconConfigService. Updated README and converted comments that used UriBeacon to EddystoneURL in the EddystoneService.h

Dependents:   mbed_EddystoneURL_Beacon_ssci mbed_EddystoneURL_Beacon_ssci mbed_EddystoneURL_Beacon_ssci

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