my version with changed conversion between duration units

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