Tomasz Trela / BLE_API

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