Updated

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