BLE FORK

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