Rtos API example

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 MBED_BLE_GAP_H__
00018 #define MBED_BLE_GAP_H__
00019 
00020 #include "BLETypes.h"
00021 #include "BLEProtocol.h"
00022 #include "GapAdvertisingData.h"
00023 #include "GapAdvertisingParams.h"
00024 #include "GapScanningParams.h"
00025 #include "GapEvents.h"
00026 #include "CallChainOfFunctionPointersWithContext.h"
00027 #include "FunctionPointerWithContext.h "
00028 #include "platform/mbed_toolchain.h"
00029 
00030 /* Forward declarations for classes that are only used for pointers or
00031    references. */
00032 class GapAdvertisingParams;
00033 class GapScanningParams;
00034 class GapAdvertisingData;
00035 
00036 /**
00037  * @addtogroup ble
00038  * @{
00039  * @addtogroup gap
00040  * @{
00041  */
00042 
00043 /**
00044  * Define device discovery, connection and link management procedures.
00045  *
00046  * - Device discovery: A device can advertise nearby peers of its existence,
00047  * identity and capabilities. Similarly, a device can scan its environment to
00048  * find advertising peers. The information acquired during the scan helps to
00049  * identify peers and understand their use. A scanner may acquire more information
00050  * about an advertising peer by sending a scan request. If the peer accepts scan
00051  * requests, it may reply with additional information about its state.
00052  *
00053  * - Connection: A bluetooth device can establish a connection to a connectable
00054  * advertising peer. Once the connection is established, both devices can
00055  * communicate using the GATT protocol. The GATT protocol allows connected
00056  * devices to expose a set of states that the other peer can discover, read and write.
00057  *
00058  * - Link Management: Connected devices may drop the connection and may adjust
00059  * connection parameters according to the power envelop needed for their
00060  * application.
00061  *
00062  * @par Accessing gap
00063  *
00064  * Instance of a Gap class for a given BLE device should be accessed using
00065  * BLE::gap(). The reference returned remains valid until the BLE instance
00066  * shut down (see BLE::shutdown()).
00067  *
00068  * @code
00069  * // assuming ble_device has been initialized
00070  * BLE& ble_device;
00071  *
00072  * Gap& gap = ble_device.gap();
00073  * @endcode
00074  *
00075  * @par Advertising
00076  *
00077  * Advertising consists of broadcasting at a regular interval a small amount of
00078  * data containing valuable informations about the device. These packets may be
00079  * scanned by peer devices listening on BLE advertising channels.
00080  *
00081  * Scanners may also request additional information from a device advertising by
00082  * sending a scan request. If the broadcaster accepts scan requests, it can reply
00083  * with a scan response packet containing additional information.
00084  *
00085  * @code
00086  * // assuming gap has been initialized
00087  * Gap& gap;
00088  *
00089  * // construct the packet to advertise
00090  * GapAdvertisingData advertising_data;
00091  *
00092  * // Add advertiser flags
00093  * advertising_data.addFlags(
00094  *    GapAdvertisingData::LE_GENERAL_DISCOVERABLE |
00095  *    GapAdvertisingData::BREDR_NOT_SUPPORTED
00096  * );
00097  *
00098  * // Add the name of the device to the advertising data
00099  * static const uint8_t device_name[] = "HRM";
00100  * advertising_data.addData(
00101  *     GapAdvertisingData::COMPLETE_LOCAL_NAME,
00102  *     device_name,
00103  *     sizeof(device_name)
00104  * );
00105  *
00106  * // set the advertising data in the gap instance, they will be used when
00107  * // advertising starts.
00108  * gap.setAdvertisingPayload(advertising_data);
00109  *
00110  * // Configure the advertising procedure
00111  * GapAdvertisingParams advertising_params(
00112  *     GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, // type of advertising
00113  *     GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000), // interval
00114  *     0 // The advertising procedure will not timeout
00115  * );
00116  *
00117  * gap.setAdvertisingParams(advertising_params);
00118  *
00119  * // start the advertising procedure, the device will advertise its flag and the
00120  * // name "HRM". Other peers will also be allowed to connect to it.
00121  * gap.startAdvertising();
00122  * @endcode
00123  *
00124  * @par Scanning
00125  *
00126  * Scanning consist of listening for peer advertising packets. From a scan, a
00127  * device can identify devices available in its environment.
00128  *
00129  * If the device scans actively, then it will send scan request to scannable
00130  * advertisers and collect their scan response.
00131  *
00132  * @code
00133  * // assuming gap has been initialized
00134  * Gap& gap;
00135  *
00136  * // Handle advertising packet by dumping their content
00137  * void handle_advertising_packet(const AdvertisementCallbackParams_t* packet)
00138  * {
00139  *    printf("Packet received: \r\n");
00140  *    printf("  - peer address: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
00141  *           packet->peerAddr[5], packet->peerAddr[4], packet->peerAddr[3],
00142  *           packet->peerAddr[2], packet->peerAddr[1], packet->peerAddr[0]);
00143  *    printf("  - rssi: %d", packet->rssi);
00144  *    printf("  - scan response: %s\r\n", packet->isScanresponse ? "true" : "false");
00145  *    printf("  - advertising type: %d\r\n", packet->type);
00146  *    printf("  - advertising type: %d\r\n", packet->type);
00147  *    printf("  - Advertising data: \r\n");
00148  *
00149  *    // parse advertising data, it is a succession of AD structures where
00150  *    // the first byte is the size of the AD structure, the second byte the
00151  *    // type of the data and remaining bytes are the value.
00152  *
00153  *    for (size_t i = 0; i < packet->advertisingDataLen; i += packet->advertisingData[i]) {
00154  *        printf("    - type: 0X%02X, data: ", packet->advertisingData[i + 1]);
00155  *        for (size_t j = 0; j < packet->advertisingData[i] - 2; ++j) {
00156  *            printf("0X%02X ", packet->advertisingData[i + 2 + j]);
00157  *        }
00158  *        printf("\r\n");
00159  *    }
00160  * }
00161  *
00162  * // set the scan parameters
00163  * gap.setScanParams(
00164  *      100, // interval between two scan window in ms
00165  *      50,  // scan window: period during which the device listen for advertising packets.
00166  *      0,   // the scan process never ends
00167  *      true // the device sends scan request to scannable peers.
00168  * );
00169  *
00170  * // start the scan procedure
00171  * gap.startScan(handle_advertising_packet);
00172  * @endcode
00173  *
00174  * @par Connection event handling
00175  *
00176  * A peer may connect device advertising connectable packets. The
00177  * advertising procedure ends as soon as the device is connected.
00178  *
00179  * A device accepting a connection request from a peer is named a peripheral,
00180  * and the device initiating the connection is named a central.
00181  *
00182  * Peripheral and central receive a connection event when the connection is
00183  * effective.
00184  *
00185  * @code
00186  * Gap& gap;
00187  *
00188  * // handle connection event
00189  * void when_connected(const ConnectionCallbackParams_t *connection_event) {
00190  *    // If this callback is entered, then the connection to a peer is effective.
00191  * }
00192  *
00193  * // register connection event handler, which will be invoked whether the device
00194  * // acts as a central or a peripheral
00195  * gap.onConnection(when_connected);
00196  * @endcode
00197  *
00198  * @par Connection initiation
00199  *
00200  * Connection is initiated central devices.
00201  *
00202  * @code
00203  * // assuming gap has been initialized
00204  * Gap& gap;
00205  *
00206  * // Handle the connection event
00207  * void handle_connection(const ConnectionCallbackParams_t* connection_event)
00208  * {
00209  *    // event handling
00210  * }
00211  *
00212  * // Handle advertising packet: connect to the first connectable device
00213  * void handle_advertising_packet(const AdvertisementCallbackParams_t* packet)
00214  * {
00215  *    if (packet->type != GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED) {
00216  *       return;
00217  *    }
00218  *
00219  *    // register connection event handler
00220  *    gap.onConnection(handle_connection);
00221  *
00222  *    Gap::ConnectionParams_t connection_parameters = {
00223  *       50, // min connection interval
00224  *       100, // max connection interval
00225  *       0, // slave latency
00226  *       600 // connection supervision timeout
00227  *    };
00228  *
00229  *    // scan parameter used to find the device to connect to
00230  *    GapScanningParams scanning_params(
00231  *      100, // interval
00232  *      100, // window
00233  *      0, // timeout
00234  *      false // active
00235  *    );
00236  *
00237  *    // Initiate the connection procedure
00238  *    gap.connect(
00239  *       packet->peerAddr,
00240  *       BLEProtocol::RANDOM_STATIC,
00241  *       &connection_parameters,
00242  *       &scanning_params
00243  *    );
00244  * }
00245  *
00246  * // set the scan parameters
00247  * gap.setScanParams(
00248  *      100, // interval between two scan window in ms
00249  *      50,  // scan window: period during which the device listen for advertising packets.
00250  *      0,   // the scan process never ends
00251  *      true // the device sends scan request to scannable peers.
00252  * );
00253  *
00254  * // start the scan procedure
00255  * gap.startScan(handle_advertising_packet);
00256  * @endcode
00257  *
00258  * @par disconnection
00259  *
00260  * The application code initiates a disconnection when it calls the
00261  * disconnect(Handle_t, DisconnectionReason_t) function.
00262  *
00263  * Disconnection may also be initiated by the remote peer or the local
00264  * controller/stack. To catch all disconnection events, application code may
00265  * set up an handler taking care of disconnection events by calling
00266  * onDisconnection().
00267  */
00268 class Gap {
00269     /*
00270      * DEPRECATION ALERT: all of the APIs in this `public` block are deprecated.
00271      * They have been relocated to the class BLEProtocol.
00272      */
00273 public:
00274     /**
00275      * Address-type for BLEProtocol addresses.
00276      *
00277      * @deprecated Use BLEProtocol::AddressType_t instead.
00278      */
00279     typedef BLEProtocol::AddressType_t AddressType_t;
00280 
00281     /**
00282      * Address-type for BLEProtocol addresses.
00283      *
00284      * @deprecated Use BLEProtocol::AddressType_t instead.
00285      */
00286     typedef BLEProtocol::AddressType_t addr_type_t;
00287 
00288     /**
00289      * Address-type for BLEProtocol addresses.
00290      *
00291      * @deprecated Use BLEProtocol::AddressType_t instead. The following
00292      * constants have been left in their deprecated state to transparently
00293      * support existing applications that may have used Gap::ADDR_TYPE_*.
00294      */
00295     enum DeprecatedAddressType_t {
00296         ADDR_TYPE_PUBLIC = BLEProtocol::AddressType::PUBLIC,
00297         ADDR_TYPE_RANDOM_STATIC = BLEProtocol::AddressType::RANDOM_STATIC,
00298         ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE,
00299         ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
00300     };
00301 
00302     /**
00303      * Length (in octets) of the BLE MAC address.
00304      */
00305     static const unsigned ADDR_LEN = BLEProtocol::ADDR_LEN;
00306 
00307     /**
00308      * 48-bit address, LSB format.
00309      *
00310      * @deprecated Use BLEProtocol::AddressBytes_t instead.
00311      */
00312     typedef BLEProtocol::AddressBytes_t Address_t;
00313 
00314     /**
00315      * 48-bit address, LSB format.
00316      *
00317      * @deprecated Use BLEProtocol::AddressBytes_t instead.
00318      */
00319     typedef BLEProtocol::AddressBytes_t address_t;
00320 
00321 public:
00322     /**
00323      * Enumeration of possible timeout sources.
00324      */
00325     enum TimeoutSource_t {
00326         /**
00327          * Advertising timeout.
00328          */
00329         TIMEOUT_SRC_ADVERTISING = 0x00,
00330 
00331         /**
00332          * Security request timeout.
00333          */
00334         TIMEOUT_SRC_SECURITY_REQUEST = 0x01,
00335 
00336         /**
00337          * Scanning timeout.
00338          */
00339         TIMEOUT_SRC_SCAN = 0x02,
00340 
00341         /**
00342          * Connection timeout.
00343          */
00344         TIMEOUT_SRC_CONN = 0x03,
00345     };
00346 
00347     /**
00348      * Enumeration of disconnection reasons.
00349      *
00350      * @important There might be a mismatch between the disconnection reason
00351      * passed to disconnect() and the disconnection event generated locally
00352      * because the disconnection reason passed to disconnect() is the
00353      * disconnection reason to be transmitted to the peer.
00354      */
00355     enum DisconnectionReason_t {
00356         /**
00357          * The connection timed out.
00358          *
00359          * @important shall not be used as a reason in disconnect().
00360          */
00361         CONNECTION_TIMEOUT = 0x08,
00362 
00363         /**
00364          * Connection terminated by the user.
00365          */
00366         REMOTE_USER_TERMINATED_CONNECTION = 0x13,
00367 
00368         /**
00369          * Remote device terminated connection due to low resources.
00370          */
00371         REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14,
00372 
00373         /**
00374          * Remote device terminated connection due to power off.
00375          */
00376         REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15,
00377 
00378         /**
00379          * Indicate that the local user or the internal
00380          * Bluetooth subsystem terminated the connection.
00381          *
00382          * @important shall not be used as a reason in disconnect().
00383          */
00384         LOCAL_HOST_TERMINATED_CONNECTION = 0x16,
00385 
00386         /**
00387          * Connection parameters were unacceptable.
00388          */
00389         CONN_INTERVAL_UNACCEPTABLE = 0x3B,
00390     };
00391 
00392     /**
00393      * Advertising policy filter modes.
00394      *
00395      * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.2.
00396      */
00397     enum AdvertisingPolicyMode_t {
00398         /**
00399          * The whitelist is not used to filter peer request during advertising.
00400          */
00401         ADV_POLICY_IGNORE_WHITELIST = 0,
00402 
00403         /**
00404          * The whitelist is used to filter peer scan requests.
00405          */
00406         ADV_POLICY_FILTER_SCAN_REQS = 1,
00407 
00408         /**
00409          * The whitelist is used to filter peer connection requests.
00410          */
00411         ADV_POLICY_FILTER_CONN_REQS = 2,
00412 
00413         /**
00414          * The whitelist is used to filter peer scan and connection requests.
00415          */
00416         ADV_POLICY_FILTER_ALL_REQS  = 3,
00417     };
00418 
00419     /**
00420      * Scanning policy filter mode.
00421      *
00422      * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.3.
00423      */
00424     enum ScanningPolicyMode_t {
00425         /**
00426          * The whitelist is not used for scanning operations.
00427          */
00428         SCAN_POLICY_IGNORE_WHITELIST = 0,
00429 
00430         /**
00431          * The whitelist is used to filter incoming advertising.
00432          */
00433         SCAN_POLICY_FILTER_ALL_ADV = 1,
00434     };
00435 
00436     /**
00437      * Connection initiation policy filter mode.
00438      *
00439      * @see Bluetooth Core Specification 4.2 (vol. 6), Part B, Section 4.4.4.
00440      */
00441     enum InitiatorPolicyMode_t {
00442         /**
00443          * Connection can be initiated to any device.
00444          */
00445         INIT_POLICY_IGNORE_WHITELIST = 0,
00446 
00447         /**
00448          * Connection initiation is restricted to the devices present in the
00449          * whitelist.
00450          */
00451         INIT_POLICY_FILTER_ALL_ADV = 1,
00452     };
00453 
00454     /**
00455      * Representation of a whitelist of addresses.
00456      */
00457     struct Whitelist_t {
00458         /**
00459          * Pointer to the array of the addresses composing the whitelist.
00460          */
00461         BLEProtocol::Address_t *addresses;
00462 
00463         /**
00464          * Number addresses in this whitelist.
00465          */
00466         uint8_t size;
00467 
00468         /**
00469          * Capacity of the array holding the addresses.
00470          */
00471         uint8_t capacity;
00472     };
00473 
00474     /**
00475      * Description of the states of the device.
00476      */
00477     struct GapState_t {
00478         /**
00479          * If set, the device is currently advertising.
00480          */
00481         unsigned advertising : 1;
00482 
00483         /**
00484          * If set, the device is connected to at least one other peer.
00485          */
00486         unsigned connected : 1;
00487     };
00488 
00489     /**
00490      * Opaque value type representing a connection handle.
00491      *
00492      * It is used to identify to refer to a specific connection across Gap,
00493      * GattClient and GattEvent API.
00494      *
00495      * @note instances are generated by in the connection callback.
00496      */
00497     typedef ble::connection_handle_t Handle_t;
00498 
00499     /**
00500      * Parameters of a BLE connection.
00501      */
00502     typedef struct {
00503         /**
00504          * Minimum interval between two connection events allowed for a
00505          * connection.
00506          *
00507          * It shall be less than or equal to maxConnectionInterval. This value,
00508          * in units of 1.25ms, is included in the range [0x0006 : 0x0C80].
00509          */
00510         uint16_t minConnectionInterval;
00511 
00512         /**
00513          * Maximum interval between two connection events allowed for a
00514          * connection.
00515          *
00516          * It shall be greater than or equal to minConnectionInterval. This
00517          * value is in unit of 1.25ms and is in the range [0x0006 : 0x0C80].
00518          */
00519         uint16_t maxConnectionInterval;
00520 
00521         /**
00522          * Number of connection events the slave can drop if it has nothing to
00523          * communicate to the master.
00524          *
00525          * This value shall be in the range [0x0000 : 0x01F3].
00526          */
00527         uint16_t slaveLatency;
00528 
00529         /**
00530          * Link supervision timeout for the connection.
00531          *
00532          * Time after which the connection is considered lost if the device
00533          * didn't receive a packet from its peer.
00534          *
00535          * It is larger than:
00536          *        (1 + slaveLatency) * maxConnectionInterval * 2
00537          *
00538          * This value is in the range [0x000A : 0x0C80] and is in unit of
00539          * 10 ms.
00540          *
00541          * @note maxConnectionInterval is in ms in the formulae above.
00542          */
00543         uint16_t connectionSupervisionTimeout;
00544     } ConnectionParams_t;
00545 
00546     /**
00547      * Enumeration of GAP roles.
00548      *
00549      * @note The BLE API does not express the broadcaster and scanner roles.
00550      *
00551      * @important A device can fulfill different roles concurrently.
00552      */
00553     enum Role_t {
00554         /**
00555          * Peripheral Role.
00556          *
00557          * The device can advertise and it can be connected by a central. It
00558          * acts as a slave when connected.
00559          *
00560          * @note A peripheral is a broadcaster.
00561          */
00562         PERIPHERAL = 0x1,
00563 
00564         /**
00565          * Central Role.
00566          *
00567          * The device can scan and initiate connection to peripherals. It
00568          * acts as the master when a connection is established.
00569          *
00570          * @note A central is a scanner.
00571          */
00572         CENTRAL = 0x2,
00573     };
00574 
00575     /**
00576      * Representation of a scanned advertising packet.
00577      *
00578      * Instances of this type are passed to the callback registered in
00579      * startScan().
00580      */
00581     struct AdvertisementCallbackParams_t {
00582         /**
00583          * BLE address of the device that has advertised the packet.
00584          */
00585         BLEProtocol::AddressBytes_t peerAddr;
00586 
00587         /**
00588          * RSSI value of the packet.
00589          */
00590         int8_t rssi;
00591 
00592         /**
00593          * Flag indicating if the packet is a response to a scan request.
00594          */
00595         bool isScanResponse;
00596 
00597         /**
00598          * Type of advertisement.
00599          */
00600         GapAdvertisingParams::AdvertisingType_t type;
00601 
00602         /**
00603          * Length of the advertisement data.
00604          */
00605         uint8_t advertisingDataLen;
00606 
00607         /**
00608          * Pointer to the advertisement packet's data.
00609          */
00610         const uint8_t *advertisingData;
00611     };
00612 
00613     /**
00614      * Type of the callback handling scanned advertisement packets.
00615      *
00616      * @see Gap::startScan().
00617      */
00618     typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> 
00619         AdvertisementReportCallback_t;
00620 
00621     /**
00622      * Connection events.
00623      *
00624      * It contains all the information related to a newly established connection.
00625      *
00626      * Instances of this structure are passed to handlers that
00627      * Gap::onConnection() registers when a connection is established.
00628      */
00629     struct ConnectionCallbackParams_t {
00630         /**
00631          * Connection handle.
00632          */
00633         Handle_t handle;
00634 
00635         /**
00636          * Connection Role of the local device.
00637          */
00638         Role_t role;
00639 
00640         /**
00641          * Type of the address the peer uses.
00642          */
00643         BLEProtocol::AddressType_t peerAddrType;
00644 
00645         /**
00646          * Address of the peer.
00647          */
00648         BLEProtocol::AddressBytes_t peerAddr;
00649 
00650         /**
00651          * Address type of the local device.
00652          */
00653         BLEProtocol::AddressType_t  ownAddrType;
00654 
00655         /**
00656          * Address of the local device.
00657          */
00658         BLEProtocol::AddressBytes_t ownAddr;
00659 
00660         /**
00661          * Connection parameters.
00662          */
00663         const ConnectionParams_t   *connectionParams;
00664 
00665         /**
00666          * Construct an instance of ConnectionCallbackParams_t.
00667          *
00668          * @param[in] handleIn Value to assign to handle.
00669          * @param[in] roleIn Value to assign to role.
00670          * @param[in] peerAddrTypeIn Value to assign to peerAddrType.
00671          * @param[in] peerAddrIn Value to assign to peerAddr.
00672          * @param[in] ownAddrTypeIn Value to assign to ownAddrType.
00673          * @param[in] ownAddrIn Value to assign to ownAddr.
00674          * @param[in] connectionParamsIn Value to assign to connectionParams.
00675          *
00676          * @note Constructor is not meant to be called by user code.
00677          * The BLE API vendor code generates ConnectionCallbackParams_t.
00678          */
00679         ConnectionCallbackParams_t(
00680             Handle_t handleIn,
00681             Role_t roleIn,
00682             BLEProtocol::AddressType_t peerAddrTypeIn,
00683             const uint8_t *peerAddrIn,
00684             BLEProtocol::AddressType_t ownAddrTypeIn,
00685             const uint8_t *ownAddrIn,
00686             const ConnectionParams_t *connectionParamsIn
00687         ) : handle(handleIn),
00688             role(roleIn),
00689             peerAddrType(peerAddrTypeIn),
00690             peerAddr(),
00691             ownAddrType(ownAddrTypeIn),
00692             ownAddr(),
00693             connectionParams(connectionParamsIn)
00694         {
00695             memcpy(peerAddr, peerAddrIn, ADDR_LEN);
00696             memcpy(ownAddr, ownAddrIn, ADDR_LEN);
00697         }
00698     };
00699 
00700     /**
00701      * Disconnection event.
00702      *
00703      * Instances of this event are passed to callbacks registered with
00704      * Gap::onDisconnection() when a connection ends.
00705      *
00706      * @note Constructor is not meant to be called by user code.
00707      * The BLE API vendor code generates ConnectionCallbackParams_t.
00708      */
00709     struct DisconnectionCallbackParams_t {
00710         /**
00711          * ID of the connection that has ended.
00712          */
00713         Handle_t handle;
00714 
00715         /**
00716          * Reason of the disconnection.
00717          */
00718         DisconnectionReason_t reason;
00719 
00720         /**
00721          * Construct a DisconnectionCallbackParams_t.
00722          *
00723          * @param[in] handleIn Value assigned to handle.
00724          * @param[in] reasonIn Value assigned to reason.
00725          */
00726         DisconnectionCallbackParams_t(
00727             Handle_t handleIn,
00728             DisconnectionReason_t reasonIn
00729         ) : handle(handleIn),
00730             reason(reasonIn)
00731         {}
00732     };
00733 
00734     /**
00735      * Number of microseconds in 1.25 milliseconds.
00736      */
00737     static const uint16_t UNIT_1_25_MS  = 1250;
00738 
00739     /**
00740      * Convert milliseconds into 1.25ms units.
00741      *
00742      * This function may be used to convert ms time of connection intervals into
00743      * the format expected for connection parameters.
00744      *
00745      * @param[in] durationInMillis The duration in milliseconds.
00746      *
00747      * @return The duration in unit of 1.25ms.
00748      */
00749     static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis)
00750     {
00751         return (durationInMillis * 1000) / UNIT_1_25_MS;
00752     }
00753 
00754     /**
00755      * Timeout event handler.
00756      *
00757      * @see Gap::onTimeout().
00758      */
00759     typedef FunctionPointerWithContext<TimeoutSource_t>  TimeoutEventCallback_t;
00760 
00761     /**
00762      * Callchain of timeout event handlers.
00763      *
00764      * @see Gap::onTimeout().
00765      */
00766     typedef CallChainOfFunctionPointersWithContext<TimeoutSource_t> 
00767         TimeoutEventCallbackChain_t;
00768 
00769     /**
00770      * Connection event handler.
00771      *
00772      * @see Gap::onConnection().
00773      */
00774     typedef FunctionPointerWithContext<const ConnectionCallbackParams_t *> 
00775         ConnectionEventCallback_t;
00776 
00777     /**
00778      * Callchain of connection event handlers.
00779      *
00780      * @see Gap::onConnection().
00781      */
00782     typedef CallChainOfFunctionPointersWithContext<const ConnectionCallbackParams_t *> 
00783         ConnectionEventCallbackChain_t;
00784 
00785     /**
00786      * Disconnection event handler.
00787      *
00788      * @see Gap::onDisconnection().
00789      */
00790     typedef FunctionPointerWithContext<const DisconnectionCallbackParams_t*> 
00791         DisconnectionEventCallback_t;
00792 
00793     /**
00794      * Callchain of disconnection event handlers.
00795      *
00796      * @see Gap::onDisconnection().
00797      */
00798     typedef CallChainOfFunctionPointersWithContext<const DisconnectionCallbackParams_t*> 
00799         DisconnectionEventCallbackChain_t;
00800 
00801     /**
00802      * Radio notification event handler.
00803      *
00804      * @see Gap::onRadioNotification().
00805      */
00806     typedef FunctionPointerWithContext<bool>  RadioNotificationEventCallback_t;
00807 
00808     /**
00809      * Gap shutdown event handler.
00810      *
00811      * @see Gap::onShutdown().
00812      */
00813     typedef FunctionPointerWithContext<const Gap *>  GapShutdownCallback_t;
00814 
00815     /**
00816      * Callchain of gap shutdown event handler.
00817      *
00818      * @see Gap::onShutdown().
00819      */
00820     typedef CallChainOfFunctionPointersWithContext<const Gap *> 
00821         GapShutdownCallbackChain_t;
00822 
00823     /*
00824      * The following functions are meant to be overridden in the platform-specific subclass.
00825      */
00826 public:
00827     /**
00828      * Set the device MAC address and type.
00829      *
00830      * The address set is used in subsequent GAP operations: scanning,
00831      * advertising and connection initiation.
00832      *
00833      * @param[in] type Type of the address to set.
00834      * @param[in] address Value of the address to set. It is ordered in
00835      * little endian. This parameter is not considered if the address type
00836      * is RANDOM_PRIVATE_RESOLVABLE or RANDOM_PRIVATE_NON_RESOLVABLE. For those
00837      * types of address, the BLE API itself generates the address.
00838      *
00839      * @note Some implementation may refuse to set a new PUBLIC address.
00840      * @note Random static address set does not change.
00841      *
00842      * @return BLE_ERROR_NONE on success.
00843      */
00844     virtual ble_error_t setAddress(
00845         BLEProtocol::AddressType_t type,
00846         const BLEProtocol::AddressBytes_t address
00847     ) {
00848         /* avoid compiler warnings about unused variables */
00849         (void)type;
00850         (void)address;
00851 
00852         /* Requesting action from porter(s): override this API if this capability
00853            is supported. */
00854         return BLE_ERROR_NOT_IMPLEMENTED;
00855     }
00856 
00857     /**
00858      * Fetch the current address and its type.
00859      *
00860      * @param[out] typeP Type of the current address set.
00861      * @param[out] address Value of the current address.
00862      *
00863      * @return BLE_ERROR_NONE on success.
00864      */
00865     virtual ble_error_t getAddress(
00866         BLEProtocol::AddressType_t *typeP,
00867         BLEProtocol::AddressBytes_t address
00868     ) {
00869         /* Avoid compiler warnings about unused variables. */
00870         (void)typeP;
00871         (void)address;
00872 
00873         /* Requesting action from porter(s): override this API if this capability
00874            is supported. */
00875         return BLE_ERROR_NOT_IMPLEMENTED;
00876     }
00877 
00878     /**
00879      * Get the minimum advertising interval in milliseconds, which can be used
00880      * for connectable advertising types.
00881      *
00882      * @return Minimum Advertising interval in milliseconds for connectable
00883      * undirected and connectable directed advertising types.
00884      */
00885     virtual uint16_t getMinAdvertisingInterval(void) const
00886     {
00887         /* Requesting action from porter(s): override this API if this capability
00888            is supported. */
00889         return 0;
00890     }
00891 
00892     /**
00893      * Get the minimum advertising interval in milliseconds, which can be
00894      * used for nonconnectable advertising type.
00895      *
00896      * @return Minimum Advertising interval in milliseconds for scannable
00897      * undirected and nonconnectable undirected event types.
00898      */
00899     virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const
00900     {
00901         /* Requesting action from porter(s): override this API if this capability
00902            is supported. */
00903         return 0;
00904     }
00905 
00906     /**
00907      * Get the maximum advertising interval in milliseconds.
00908      *
00909      * @return Maximum Advertising interval in milliseconds.
00910      */
00911     virtual uint16_t getMaxAdvertisingInterval(void) const
00912     {
00913         /* Requesting action from porter(s): override this API if this capability
00914            is supported. */
00915         return 0xFFFF;
00916     }
00917 
00918     /**
00919      * Stop the ongoing advertising procedure.
00920      *
00921      * @note The current advertising parameters remain in effect.
00922      *
00923      * @retval BLE_ERROR_NONE if the advertising procedure has been successfully
00924      * stopped.
00925      */
00926     virtual ble_error_t stopAdvertising(void)
00927     {
00928         /* Requesting action from porter(s): override this API if this capability
00929            is supported. */
00930         return BLE_ERROR_NOT_IMPLEMENTED;
00931     }
00932 
00933     /**
00934      * Stop the ongoing scanning procedure.
00935      *
00936      * The current scanning parameters remain in effect.
00937      *
00938      * @retval BLE_ERROR_NONE if successfully stopped scanning procedure.
00939      */
00940     virtual ble_error_t stopScan()
00941     {
00942         /* Requesting action from porter(s): override this API if this capability
00943            is supported. */
00944         return BLE_ERROR_NOT_IMPLEMENTED;
00945     }
00946 
00947     /**
00948      * Initiate a connection to a peer.
00949      *
00950      * Once the connection is established, a ConnectionCallbackParams_t event is
00951      * emitted to handlers that have been registered with onConnection().
00952      *
00953      * @param[in] peerAddr MAC address of the peer. It must be in LSB format.
00954      * @param[in] peerAddrType Address type of the peer.
00955      * @param[in] connectionParams Connection parameters to use.
00956      * @param[in] scanParams Scan parameters used to find the peer.
00957      *
00958      * @return BLE_ERROR_NONE if connection establishment procedure is started
00959      * successfully. The connectionCallChain (if set) is invoked upon
00960      * a connection event.
00961      */
00962     virtual ble_error_t connect(
00963         const BLEProtocol::AddressBytes_t peerAddr,
00964         BLEProtocol::AddressType_t peerAddrType,
00965         const ConnectionParams_t *connectionParams,
00966         const GapScanningParams *scanParams
00967     ) {
00968         /* Avoid compiler warnings about unused variables. */
00969         (void)peerAddr;
00970         (void)peerAddrType;
00971         (void)connectionParams;
00972         (void)scanParams;
00973 
00974         /* Requesting action from porter(s): override this API if this capability
00975            is supported. */
00976         return BLE_ERROR_NOT_IMPLEMENTED;
00977     }
00978 
00979     /**
00980      * Initiate a connection to a peer.
00981      *
00982      * @see connect()
00983      *
00984      * @deprecated  This funtion overloads Gap::connect(
00985      *      const BLEProtocol::Address_t peerAddr,
00986      *      BLEProtocol::AddressType_t peerAddrType,
00987      *      const ConnectionParams_t *connectionParams,
00988      *      const GapScanningParams *scanParams
00989      * )
00990      * to maintain backward compatibility for changes from Gap::AddressType_t to
00991      * BLEProtocol::AddressType_t.
00992      */
00993     MBED_DEPRECATED("Gap::DeprecatedAddressType_t is deprecated, use BLEProtocol::AddressType_t instead")
00994     ble_error_t connect(
00995         const BLEProtocol::AddressBytes_t peerAddr,
00996         DeprecatedAddressType_t peerAddrType,
00997         const ConnectionParams_t *connectionParams,
00998         const GapScanningParams *scanParams
00999     ) {
01000         return connect(
01001             peerAddr,
01002             (BLEProtocol::AddressType_t)
01003             peerAddrType,
01004             connectionParams,
01005             scanParams
01006         );
01007     }
01008 
01009     /**
01010      * Initiate a disconnection procedure.
01011      *
01012      * Once the disconnection procedure has completed a
01013      * DisconnectionCallbackParams_t, the event is emitted to handlers that
01014      * have been registered with onDisconnection().
01015      *
01016      * @param[in] reason Reason of the disconnection transmitted to the peer.
01017      * @param[in] connectionHandle Handle of the connection to end.
01018      *
01019      * @return  BLE_ERROR_NONE if the disconnection procedure successfully
01020      * started.
01021      */
01022     virtual ble_error_t disconnect(
01023         Handle_t connectionHandle, DisconnectionReason_t reason
01024     ) {
01025         /* avoid compiler warnings about unused variables */
01026         (void)connectionHandle;
01027         (void)reason;
01028 
01029         /* Requesting action from porter(s): override this API if this capability
01030            is supported. */
01031         return BLE_ERROR_NOT_IMPLEMENTED;
01032     }
01033 
01034     /**
01035      * Initiate a disconnection procedure.
01036      *
01037      * @deprecated This version of disconnect() doesn't take a connection handle.
01038      * It works reliably only for stacks that are limited to a single connection.
01039      * Use Gap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
01040      * instead.
01041      *
01042      * @param[in] reason The reason for disconnection; to be sent back to the peer.
01043      *
01044      * @return BLE_ERROR_NONE if disconnection was successful.
01045      */
01046     MBED_DEPRECATED("Use disconnect(Handle_t, DisconnectionReason_t) instead.")
01047     virtual ble_error_t disconnect(DisconnectionReason_t reason) {
01048         /* Avoid compiler warnings about unused variables. */
01049         (void)reason;
01050 
01051         /* Requesting action from porter(s): override this API if this capability
01052            is supported. */
01053         return BLE_ERROR_NOT_IMPLEMENTED;
01054     }
01055 
01056     /**
01057      * Returned the preferred connection parameters exposed in the GATT Generic
01058      * Access Service.
01059      *
01060      * @param[out] params Structure where the parameters are stored.
01061      *
01062      * @return BLE_ERROR_NONE if the parameters were successfully filled into
01063      * @p params.
01064      */
01065     virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params)
01066     {
01067         /* Avoid compiler warnings about unused variables. */
01068         (void)params;
01069 
01070         /* Requesting action from porter(s): override this API if this capability
01071            is supported. */
01072         return BLE_ERROR_NOT_IMPLEMENTED;
01073     }
01074 
01075     /**
01076      * Set the value of the preferred connection parameters exposed in the GATT
01077      * Generic Access Service.
01078      *
01079      * A connected peer may read the characteristic exposing these parameters
01080      * and request an update of the connection parameters to accomodate the
01081      * local device.
01082      *
01083      * @param[in] params Value of the preferred connection parameters.
01084      *
01085      * @return BLE_ERROR_NONE if the preferred connection params were set
01086      * correctly.
01087      */
01088     virtual ble_error_t setPreferredConnectionParams(
01089         const ConnectionParams_t *params
01090     ) {
01091         /* Avoid compiler warnings about unused variables. */
01092         (void)params;
01093 
01094         /* Requesting action from porter(s): override this API if this capability
01095            is supported. */
01096         return BLE_ERROR_NOT_IMPLEMENTED;
01097     }
01098 
01099     /**
01100      * Update connection parameters of an existing connection.
01101      *
01102      * In the central role, this initiates a Link Layer connection parameter
01103      * update procedure. In the peripheral role, this sends the corresponding
01104      * L2CAP request and waits for the central to perform the procedure.
01105      *
01106      * @param[in] handle Connection Handle.
01107      * @param[in] params Pointer to desired connection parameters.
01108      *
01109      * @return BLE_ERROR_NONE if the connection parameters were updated correctly.
01110      */
01111     virtual ble_error_t updateConnectionParams(
01112         Handle_t handle,
01113         const ConnectionParams_t *params
01114     ) {
01115         /* avoid compiler warnings about unused variables */
01116         (void)handle;
01117         (void)params;
01118 
01119         /* Requesting action from porter(s): override this API if this capability
01120            is supported. */
01121         return BLE_ERROR_NOT_IMPLEMENTED;
01122     }
01123 
01124     /**
01125      * Set the value of the device name characteristic in the Generic Access
01126      * Service.
01127      *
01128      * @param[in] deviceName The new value for the device-name. This is a
01129      * UTF-8 encoded, <b>NULL-terminated</b> string.
01130      *
01131      * @return BLE_ERROR_NONE if the device name was set correctly.
01132      */
01133     virtual ble_error_t setDeviceName(const uint8_t *deviceName) {
01134         /* Avoid compiler warnings about unused variables. */
01135         (void)deviceName;
01136 
01137         /* Requesting action from porter(s): override this API if this capability
01138            is supported. */
01139         return BLE_ERROR_NOT_IMPLEMENTED;
01140     }
01141 
01142     /**
01143      * Get the value of the device name characteristic in the Generic Access
01144      * Service.
01145      *
01146      * To obtain the length of the deviceName value, this function is
01147      * invoked with the @p deviceName parameter set to NULL.
01148      *
01149      * @param[out] deviceName Pointer to an empty buffer where the UTF-8
01150      * <b>non NULL-terminated<b> string is placed.
01151      *
01152      * @param[in,out] lengthP Length of the @p deviceName buffer. If the device
01153      * name is successfully copied, then the length of the device name
01154      * string (excluding the null terminator) replaces this value.
01155      *
01156      * @return BLE_ERROR_NONE if the device name was fetched correctly from the
01157      * underlying BLE stack.
01158      *
01159      * @note If the device name is longer than the size of the supplied buffer,
01160      * length returns the complete device name length and not the number of
01161      * bytes actually returned in deviceName. The application may use this
01162      * information to retry with a suitable buffer size.
01163      */
01164     virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP)
01165     {
01166         /* avoid compiler warnings about unused variables */
01167         (void)deviceName;
01168         (void)lengthP;
01169 
01170         /* Requesting action from porter(s): override this API if this capability
01171            is supported. */
01172         return BLE_ERROR_NOT_IMPLEMENTED;
01173     }
01174 
01175     /**
01176      * Set the value of the appearance characteristic in the GAP service.
01177      *
01178      * @param[in] appearance The new value for the device-appearance.
01179      *
01180      * @return BLE_ERROR_NONE if the new appearance was set correctly.
01181      */
01182     virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance)
01183     {
01184         /* Avoid compiler warnings about unused variables. */
01185         (void)appearance;
01186 
01187         /* Requesting action from porter(s): override this API if this capability
01188            is supported. */
01189         return BLE_ERROR_NOT_IMPLEMENTED;
01190     }
01191 
01192     /**
01193      * Get the value of the appearance characteristic in the GAP service.
01194      *
01195      * @param[out] appearance The current device-appearance value.
01196      *
01197      * @return BLE_ERROR_NONE if the device-appearance was fetched correctly
01198      * from the underlying BLE stack.
01199      */
01200     virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP)
01201     {
01202         /* Avoid compiler warnings about unused variables. */
01203         (void)appearanceP;
01204 
01205         /* Requesting action from porter(s): override this API if this capability
01206            is supported. */
01207         return BLE_ERROR_NOT_IMPLEMENTED;
01208     }
01209 
01210     /**
01211      * Set the radio's transmit power.
01212      *
01213      * @param[in] txPower Radio's transmit power in dBm.
01214      *
01215      * @return BLE_ERROR_NONE if the new radio's transmit power was set
01216      * correctly.
01217      */
01218     virtual ble_error_t setTxPower(int8_t txPower)
01219     {
01220         /* Avoid compiler warnings about unused variables. */
01221         (void)txPower;
01222 
01223         /* Requesting action from porter(s): override this API if this capability
01224            is supported. */
01225         return BLE_ERROR_NOT_IMPLEMENTED;
01226     }
01227 
01228     /**
01229      * Query the underlying stack for allowed Tx power values.
01230      *
01231      * @param[out] valueArrayPP Receive the immutable array of Tx values.
01232      * @param[out] countP Receive the array's size.
01233      */
01234     virtual void getPermittedTxPowerValues(
01235         const int8_t **valueArrayPP, size_t *countP
01236     ) {
01237         /* Avoid compiler warnings about unused variables. */
01238         (void)valueArrayPP;
01239         (void)countP;
01240 
01241         /* Requesting action from porter(s): override this API if this capability
01242            is supported. */
01243         *countP = 0;
01244     }
01245 
01246     /**
01247      * Get the maximum size of the whitelist.
01248      *
01249      * @return Maximum size of the whitelist.
01250      *
01251      * @note If using Mbed OS, you can configure the size of the whitelist by
01252      * setting the YOTTA_CFG_WHITELIST_MAX_SIZE macro in your yotta config file.
01253      */
01254     virtual uint8_t getMaxWhitelistSize(void) const
01255     {
01256         return 0;
01257     }
01258 
01259     /**
01260      * Get the Link Layer to use the internal whitelist when scanning,
01261      * advertising or initiating a connection depending on the filter policies.
01262      *
01263      * @param[in,out] whitelist Define the whitelist instance which is used
01264      * to store the whitelist requested. In input, the caller provisions memory.
01265      *
01266      * @return BLE_ERROR_NONE if the implementation's whitelist was successfully
01267      * copied into the supplied reference.
01268      *
01269      * @experimental
01270      */
01271     virtual ble_error_t getWhitelist(Whitelist_t &whitelist) const
01272     {
01273         (void) whitelist;
01274         return BLE_ERROR_NOT_IMPLEMENTED;
01275     }
01276 
01277     /**
01278      * Set the value of the whitelist to be used during GAP procedures.
01279      *
01280      * @param[in] whitelist A reference to a whitelist containing the addresses
01281      * to be copied to the internal whitelist.
01282      *
01283      * @return BLE_ERROR_NONE if the implementation's whitelist was successfully
01284      * populated with the addresses in the given whitelist.
01285      *
01286      * @note The whitelist must not contain addresses of type @ref
01287      * BLEProtocol::AddressType_t::RANDOM_PRIVATE_NON_RESOLVABLE. This
01288      * results in a @ref BLE_ERROR_INVALID_PARAM because the remote peer might
01289      * change its private address at any time, and it is not possible to resolve
01290      * it.
01291      *
01292      * @note If the input whitelist is larger than @ref getMaxWhitelistSize(),
01293      * then @ref BLE_ERROR_PARAM_OUT_OF_RANGE is returned.
01294      */
01295     virtual ble_error_t setWhitelist(const Whitelist_t &whitelist)
01296     {
01297         (void) whitelist;
01298         return BLE_ERROR_NOT_IMPLEMENTED;
01299     }
01300 
01301     /**
01302      * Set the advertising policy filter mode to be used during the next
01303      * advertising procedure.
01304      *
01305      * @param[in] mode New advertising policy filter mode.
01306      *
01307      * @return BLE_ERROR_NONE if the specified policy filter mode was set
01308      * successfully.
01309      */
01310     virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode)
01311     {
01312         (void) mode;
01313         return BLE_ERROR_NOT_IMPLEMENTED;
01314     }
01315 
01316     /**
01317      * Set the scan policy filter mode to be used during the next scan procedure.
01318      *
01319      * @param[in] mode New scan policy filter mode.
01320      *
01321      * @return BLE_ERROR_NONE if the specified policy filter mode was set
01322      * successfully.
01323      */
01324     virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode)
01325     {
01326         (void) mode;
01327         return BLE_ERROR_NOT_IMPLEMENTED;
01328     }
01329 
01330     /**
01331      * Set the initiator policy filter mode to be used during the next connection
01332      * initiation.
01333      *
01334      * @param[in] mode New initiator policy filter mode.
01335      *
01336      * @return BLE_ERROR_NONE if the specified policy filter mode was set
01337      * successfully.
01338      */
01339     virtual ble_error_t setInitiatorPolicyMode(InitiatorPolicyMode_t mode)
01340     {
01341         (void) mode;
01342         return BLE_ERROR_NOT_IMPLEMENTED;
01343     }
01344 
01345     /**
01346      * Get the current advertising policy filter mode.
01347      *
01348      * @return The current advertising policy filter mode.
01349      */
01350     virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const
01351     {
01352         return ADV_POLICY_IGNORE_WHITELIST;
01353     }
01354 
01355     /**
01356      * Get the current scan policy filter mode.
01357      *
01358      * @return The current scan policy filter mode.
01359      */
01360     virtual ScanningPolicyMode_t getScanningPolicyMode(void) const
01361     {
01362         return SCAN_POLICY_IGNORE_WHITELIST;
01363     }
01364 
01365     /**
01366      * Get the current initiator policy filter mode.
01367      *
01368      * @return The current scan policy filter mode.
01369      */
01370     virtual InitiatorPolicyMode_t getInitiatorPolicyMode(void) const
01371     {
01372         return INIT_POLICY_IGNORE_WHITELIST;
01373     }
01374 
01375 protected:
01376     /* Override the following in the underlying adaptation layer to provide the
01377       functionality of scanning. */
01378 
01379     /**
01380      * Start scanning procedure in the underlying BLE stack.
01381      *
01382      * @param[in] scanningParams Parameters of the scan procedure.
01383      *
01384      * @return BLE_ERROR_NONE if the scan procedure was successfully started.
01385      */
01386     virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams)
01387     {
01388         (void)scanningParams;
01389         /* Requesting action from porter(s): override this API if this capability
01390            is supported. */
01391         return BLE_ERROR_NOT_IMPLEMENTED;
01392     }
01393 
01394     /*
01395      * APIs with nonvirtual implementations.
01396      */
01397 public:
01398     /**
01399      * Get the current advertising and connection states of the device.
01400      *
01401      * @return The current GAP state of the device.
01402      */
01403     GapState_t getState(void) const
01404     {
01405         return state;
01406     }
01407 
01408     /**
01409      * Set the advertising type to use during the advertising procedure.
01410      *
01411      * @param[in] advType New type of advertising to use.
01412      */
01413     void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType)
01414     {
01415         _advParams.setAdvertisingType(advType);
01416     }
01417 
01418     /**
01419      * Set the advertising interval.
01420      *
01421      * @param[in] interval Advertising interval in units of milliseconds.
01422      * Advertising is disabled if interval is 0. If interval is smaller than
01423      * the minimum supported value, then the minimum supported value is used
01424      * instead. This minimum value can be discovered using
01425      * getMinAdvertisingInterval().
01426      *
01427      * This field must be set to 0 if connectionMode is equal
01428      * to ADV_CONNECTABLE_DIRECTED.
01429      *
01430      * @note  Decreasing this value allows central devices to detect a
01431      * peripheral faster, at the expense of the radio using more power
01432      * due to the higher data transmit rate.
01433      */
01434     void setAdvertisingInterval(uint16_t interval)
01435     {
01436         if (interval == 0) {
01437             stopAdvertising();
01438         } else if (interval < getMinAdvertisingInterval()) {
01439             interval = getMinAdvertisingInterval();
01440         }
01441         _advParams.setInterval(interval);
01442     }
01443 
01444     /**
01445      * Set the advertising duration.
01446      *
01447      * A timeout event is genenerated once the advertising period expired.
01448      *
01449      * @param[in] timeout Advertising timeout (in seconds) between 0x1 and 0x3FFF.
01450      * The special value 0 may be used to disable the advertising timeout.
01451      */
01452     void setAdvertisingTimeout(uint16_t timeout)
01453     {
01454         _advParams.setTimeout(timeout);
01455     }
01456 
01457     /**
01458      * Start the advertising procedure.
01459      *
01460      * @return BLE_ERROR_NONE if the device started advertising successfully.
01461      */
01462     ble_error_t startAdvertising(void)
01463     {
01464         ble_error_t rc;
01465         if ((rc = startAdvertising(_advParams)) == BLE_ERROR_NONE) {
01466             state.advertising = 1;
01467         }
01468         return rc;
01469     }
01470 
01471     /**
01472      * Reset the value of the advertising payload advertised.
01473      */
01474     void clearAdvertisingPayload(void)
01475     {
01476         _advPayload.clear();
01477         setAdvertisingData(_advPayload, _scanResponse);
01478     }
01479 
01480     /**
01481      * Set gap flags in the advertising payload.
01482      *
01483      * A call to this function is equivalent to:
01484      *
01485      * @code
01486      * Gap &gap;
01487      *
01488      * GapAdvertisingData payload = gap.getAdvertisingPayload();
01489      * payload.addFlags(flags);
01490      * gap.setAdvertisingPayload(payload);
01491      * @endcode
01492      *
01493      * @param[in] flags The flags to be added.
01494      *
01495      * @return BLE_ERROR_NONE if the data was successfully added to the
01496      * advertising payload.
01497      */
01498     ble_error_t accumulateAdvertisingPayload(uint8_t flags)
01499     {
01500         GapAdvertisingData advPayloadCopy = _advPayload;
01501         ble_error_t rc;
01502         if ((rc = advPayloadCopy.addFlags(flags)) != BLE_ERROR_NONE) {
01503             return rc;
01504         }
01505 
01506         rc = setAdvertisingData(advPayloadCopy, _scanResponse);
01507         if (rc == BLE_ERROR_NONE) {
01508             _advPayload = advPayloadCopy;
01509         }
01510 
01511         return rc;
01512     }
01513 
01514     /**
01515      * Set the appearance field in the advertising payload.
01516      *
01517      * A call to this function is equivalent to:
01518      *
01519      * @code
01520      * Gap &gap;
01521      *
01522      * GapAdvertisingData payload = gap.getAdvertisingPayload();
01523      * payload.addAppearance(app);
01524      * gap.setAdvertisingPayload(payload);
01525      * @endcode
01526      *
01527      * @param[in] app The appearance to advertise.
01528      *
01529      * @return BLE_ERROR_NONE if the data was successfully added to the
01530      * advertising payload.
01531      */
01532     ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app)
01533     {
01534         GapAdvertisingData advPayloadCopy = _advPayload;
01535         ble_error_t rc;
01536         if ((rc = advPayloadCopy.addAppearance(app)) != BLE_ERROR_NONE) {
01537             return rc;
01538         }
01539 
01540         rc = setAdvertisingData(advPayloadCopy, _scanResponse);
01541         if (rc == BLE_ERROR_NONE) {
01542             _advPayload = advPayloadCopy;
01543         }
01544 
01545         return rc;
01546     }
01547 
01548     /**
01549      * Set the Tx Power field in the advertising payload.
01550      *
01551      * A call to this function is equivalent to:
01552      *
01553      * @code
01554      * Gap &gap;
01555      *
01556      * GapAdvertisingData payload = gap.getAdvertisingPayload();
01557      * payload.addTxPower(power);
01558      * gap.setAdvertisingPayload(payload);
01559      * @endcode
01560      *
01561      * @param[in] power Transmit power in dBm used by the controller to advertise.
01562      *
01563      * @return BLE_ERROR_NONE if the data was successfully added to the
01564      * advertising payload.
01565      */
01566     ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power)
01567     {
01568         GapAdvertisingData advPayloadCopy = _advPayload;
01569         ble_error_t rc;
01570         if ((rc = advPayloadCopy.addTxPower(power)) != BLE_ERROR_NONE) {
01571             return rc;
01572         }
01573 
01574         rc = setAdvertisingData(advPayloadCopy, _scanResponse);
01575         if (rc == BLE_ERROR_NONE) {
01576             _advPayload = advPayloadCopy;
01577         }
01578 
01579         return rc;
01580     }
01581 
01582     /**
01583      * Add a new field in the advertising payload.
01584      *
01585      * A call to this function is equivalent to:
01586      *
01587      * @code
01588      * Gap &gap;
01589      *
01590      * GapAdvertisingData payload = gap.getAdvertisingPayload();
01591      * payload.addData(type, data, len);
01592      * gap.setAdvertisingPayload(payload);
01593      * @endcode
01594      *
01595      * @param[in] type Identity of the field being added.
01596      * @param[in] data Buffer containing the value of the field.
01597      * @param[in] len Length of the data buffer.
01598      *
01599      * @return BLE_ERROR_NONE if the advertisement payload was updated based on
01600      * matching AD type; otherwise, an appropriate error.
01601      *
01602      * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
01603      * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
01604      * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
01605      * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
01606      * supplied value is appended to the values previously added to the payload.
01607      */
01608     ble_error_t accumulateAdvertisingPayload(
01609         GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len
01610     ) {
01611         GapAdvertisingData advPayloadCopy = _advPayload;
01612         ble_error_t rc;
01613         if ((rc = advPayloadCopy.addData(type, data, len)) != BLE_ERROR_NONE) {
01614             return rc;
01615         }
01616 
01617         rc = setAdvertisingData(advPayloadCopy, _scanResponse);
01618         if (rc == BLE_ERROR_NONE) {
01619             _advPayload = advPayloadCopy;
01620         }
01621 
01622         return rc;
01623     }
01624 
01625     /**
01626      * Update a particular field in the advertising payload.
01627      *
01628      * A call to this function is equivalent to:
01629      *
01630      * @code
01631      * Gap &gap;
01632      *
01633      * GapAdvertisingData payload = gap.getAdvertisingPayload();
01634      * payload.updateData(type, data, len);
01635      * gap.setAdvertisingPayload(payload);
01636      * @endcode
01637      *
01638      *
01639      * @param[in] type Id of the field to update.
01640      * @param[in] data data buffer containing the new value of the field.
01641      * @param[in] len Length of the data buffer.
01642      *
01643      * @note If advertisements are enabled, then the update takes effect
01644      * immediately.
01645      *
01646      * @return BLE_ERROR_NONE if the advertisement payload was updated based on
01647      * matching AD type; otherwise, an appropriate error.
01648      */
01649     ble_error_t updateAdvertisingPayload(
01650         GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len
01651     ) {
01652         GapAdvertisingData advPayloadCopy = _advPayload;
01653         ble_error_t rc;
01654         if ((rc = advPayloadCopy.updateData(type, data, len)) != BLE_ERROR_NONE) {
01655             return rc;
01656         }
01657 
01658         rc = setAdvertisingData(advPayloadCopy, _scanResponse);
01659         if (rc == BLE_ERROR_NONE) {
01660             _advPayload = advPayloadCopy;
01661         }
01662 
01663         return rc;
01664     }
01665 
01666     /**
01667      * Set the value of the payload advertised.
01668      *
01669      * @param[in] payload A reference to a user constructed advertisement
01670      * payload to set.
01671      *
01672      * @return BLE_ERROR_NONE if the advertisement payload was successfully
01673      * set.
01674      */
01675     ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload)
01676     {
01677         ble_error_t rc = setAdvertisingData(payload, _scanResponse);
01678         if (rc == BLE_ERROR_NONE) {
01679             _advPayload = payload;
01680         }
01681 
01682         return rc;
01683     }
01684 
01685     /**
01686      * Get a reference to the current advertising payload.
01687      *
01688      * @return A reference to the current advertising payload.
01689      */
01690     const GapAdvertisingData &getAdvertisingPayload(void) const
01691     {
01692         return _advPayload;
01693     }
01694 
01695     /**
01696      * Add a new field in the advertising payload.
01697      *
01698      * @param[in] type AD type identifier.
01699      * @param[in] data buffer containing AD data.
01700      * @param[in] len Length of the data buffer.
01701      *
01702      * @return BLE_ERROR_NONE if the data was successfully added to the scan
01703      * response payload.
01704      */
01705     ble_error_t accumulateScanResponse(
01706         GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len
01707     ) {
01708         GapAdvertisingData scanResponseCopy = _scanResponse;
01709         ble_error_t rc;
01710         if ((rc = scanResponseCopy.addData(type, data, len)) != BLE_ERROR_NONE) {
01711             return rc;
01712         }
01713 
01714         rc = setAdvertisingData(_advPayload, scanResponseCopy);
01715         if (rc == BLE_ERROR_NONE) {
01716             _scanResponse = scanResponseCopy;
01717         }
01718 
01719         return rc;
01720     }
01721 
01722     /**
01723      * Reset the content of the scan response.
01724      *
01725      * @note This should be followed by a call to Gap::setAdvertisingPayload()
01726      * or Gap::startAdvertising() before the update takes effect.
01727      */
01728     void clearScanResponse(void) {
01729         _scanResponse.clear();
01730         setAdvertisingData(_advPayload, _scanResponse);
01731     }
01732 
01733     /**
01734      * Set the parameters used during a scan procedure.
01735      *
01736      * @param[in] interval in ms between the start of two consecutive scan windows.
01737      * That value is greater or equal to the scan window value. The
01738      * maximum allowed value is 10.24ms.
01739      *
01740      * @param[in] window Period in ms during which the scanner listens to
01741      * advertising channels. That value is in the range 2.5ms to 10.24s.
01742      *
01743      * @param[in] timeout Duration in seconds of the scan procedure if any. The
01744      * special value 0 disable specific duration of the scan procedure.
01745      *
01746      * @param[in] activeScanning If set to true, then the scanner sends scan
01747      * requests to a scannable or connectable advertiser. If set to false, then the
01748      * scanner does not send any request during the scan procedure.
01749      *
01750      * @return BLE_ERROR_NONE if the scan parameters were correctly set.
01751      *
01752      * @note The scanning window divided by the interval determines the duty
01753      * cycle for scanning. For example, if the interval is 100ms and the window
01754      * is 10ms, then the controller scans for 10 percent of the time.
01755      *
01756      * @note If the interval and the window are set to the same value, then the
01757      * device scans continuously during the scan procedure. The scanning
01758      * frequency changes at every interval.
01759      *
01760      * @note Once the scanning parameters have been configured, scanning can be
01761      * enabled by using startScan().
01762      *
01763      * @note The scan interval and window are recommendations to the BLE stack.
01764      */
01765     ble_error_t setScanParams(
01766         uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX,
01767         uint16_t window = GapScanningParams::SCAN_WINDOW_MAX,
01768         uint16_t timeout = 0,
01769         bool activeScanning = false
01770     ) {
01771         ble_error_t rc;
01772         if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) &&
01773             ((rc = _scanningParams.setWindow(window))     == BLE_ERROR_NONE) &&
01774             ((rc = _scanningParams.setTimeout(timeout))   == BLE_ERROR_NONE)) {
01775             _scanningParams.setActiveScanning(activeScanning);
01776             return BLE_ERROR_NONE;
01777         }
01778 
01779         return rc;
01780     }
01781 
01782     /**
01783      * Set the interval parameter used during scanning procedures.
01784      *
01785      * @param[in] interval Interval in ms between the start of two consecutive
01786      * scan windows. That value is greater or equal to the scan window value.
01787      * The maximum allowed value is 10.24ms.
01788      *
01789      * @return BLE_ERROR_NONE if the scan interval was correctly set.
01790      */
01791     ble_error_t setScanInterval(uint16_t interval)
01792     {
01793         return _scanningParams.setInterval(interval);
01794     }
01795 
01796     /**
01797      * Set the window parameter used during scanning procedures.
01798      *
01799      * @param[in] window Period in ms during which the scanner listens to
01800      * advertising channels. That value is in the range 2.5ms to 10.24s.
01801      *
01802      * @return BLE_ERROR_NONE if the scan window was correctly set.
01803      *
01804      * @note If scanning is already active, the updated value of scanWindow
01805      * is propagated to the underlying BLE stack.
01806      */
01807     ble_error_t setScanWindow(uint16_t window)
01808     {
01809         ble_error_t rc;
01810         if ((rc = _scanningParams.setWindow(window)) != BLE_ERROR_NONE) {
01811             return rc;
01812         }
01813 
01814         /* If scanning is already active, propagate the new setting to the stack. */
01815         if (scanningActive) {
01816             return startRadioScan(_scanningParams);
01817         }
01818 
01819         return BLE_ERROR_NONE;
01820     }
01821 
01822     /**
01823      * Set the timeout parameter used during scanning procedures.
01824      *
01825      * @param[in] timeout Duration in seconds of the scan procedure if any. The
01826      * special value 0 disables specific duration of the scan procedure.
01827      *
01828      * @return BLE_ERROR_NONE if the scan timeout was correctly set.
01829      *
01830      * @note If scanning is already active, the updated value of scanTimeout
01831      * is propagated to the underlying BLE stack.
01832      */
01833     ble_error_t setScanTimeout(uint16_t timeout)
01834     {
01835         ble_error_t rc;
01836         if ((rc = _scanningParams.setTimeout(timeout)) != BLE_ERROR_NONE) {
01837             return rc;
01838         }
01839 
01840         /* If scanning is already active, propagate the new settings to the stack. */
01841         if (scanningActive) {
01842             return startRadioScan(_scanningParams);
01843         }
01844 
01845         return BLE_ERROR_NONE;
01846     }
01847 
01848     /**
01849      * Enable or disable active scanning.
01850      *
01851      * @param[in] activeScanning If set to true, then the scanner sends scan
01852      * requests to a scannable or connectable advertiser. If set to false then the
01853      * scanner does not send any request during the scan procedure.
01854      *
01855      * @return BLE_ERROR_NONE if active scanning was successfully set.
01856      *
01857      * @note If scanning is already in progress, then active scanning is
01858      * enabled for the underlying BLE stack.
01859      */
01860     ble_error_t setActiveScanning(bool activeScanning)
01861     {
01862         _scanningParams.setActiveScanning(activeScanning);
01863 
01864         /* If scanning is already active, propagate the new settings to the stack. */
01865         if (scanningActive) {
01866             return startRadioScan(_scanningParams);
01867         }
01868 
01869         return BLE_ERROR_NONE;
01870     }
01871 
01872     /**
01873      * Start the scanning procedure.
01874      *
01875      * Packets received during the scan procedure are forwarded to the
01876      * scan packet handler passed as argument to this function.
01877      *
01878      * @param[in] callback Advertisement packet event handler. Upon reception
01879      * of an advertising packet, the packet is forwarded to @p callback.
01880      *
01881      * @return BLE_ERROR_NONE if the device successfully started the scan
01882      *         procedure.
01883      *
01884      * @note The parameters used by the procedure are defined by setScanParams().
01885      */
01886     ble_error_t startScan(
01887         void (*callback)(const AdvertisementCallbackParams_t *params)
01888     ) {
01889         ble_error_t err = BLE_ERROR_NONE;
01890         if (callback) {
01891             if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
01892                 scanningActive = true;
01893                 onAdvertisementReport.attach(callback);
01894             }
01895         }
01896 
01897         return err;
01898     }
01899 
01900     /**
01901      * Start the scanning procedure.
01902      *
01903      * Packets received during the scan procedure are forwarded to the
01904      * scan packet handler passed as argument to this function.
01905      *
01906      * @param[in] object Instance used to invoke @p callbackMember.
01907      *
01908      * @param[in] callbackMember Advertisement packet event handler. Upon
01909      * reception of an advertising packet, the packet is forwarded to @p
01910      * callback invoked from @p object.
01911      *
01912      * @return BLE_ERROR_NONE if the device successfully started the scan
01913      * procedure.
01914      *
01915      * @note The parameters used by the procedure are defined by setScanParams().
01916      */
01917     template<typename T>
01918     ble_error_t startScan(
01919         T *object,
01920         void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)
01921     ) {
01922         ble_error_t err = BLE_ERROR_NONE;
01923         if (object && callbackMember) {
01924             if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
01925                 scanningActive = true;
01926                 onAdvertisementReport.attach(object, callbackMember);
01927             }
01928         }
01929 
01930         return err;
01931     }
01932 
01933     /**
01934      * Enable radio-notification events.
01935      *
01936      * Radio Notification is a feature that notifies the application when the
01937      * radio is in use.
01938      *
01939      * The ACTIVE signal is sent before the radio event starts. The nACTIVE
01940      * signal is sent at the end of the radio event. The application programmer can
01941      * use these signals to synchronize application logic with radio
01942      * activity. For example, the ACTIVE signal can be used to shut off external
01943      * devices, to manage peak current drawn during periods when the radio is on
01944      * or to trigger sensor data collection for transmission in the Radio Event.
01945      *
01946      * @return BLE_ERROR_NONE on successful initialization, otherwise an error code.
01947      */
01948     virtual ble_error_t initRadioNotification(void)
01949     {
01950         /* Requesting action from porter(s): override this API if this capability
01951            is supported. */
01952         return BLE_ERROR_NOT_IMPLEMENTED;
01953     }
01954 
01955 private:
01956     /**
01957      * Set the advertising data and scan response in the vendor subsytem.
01958      *
01959      * @param[in] advData Advertising data to set.
01960      * @param[in] scanResponse Scan response to set.
01961      *
01962      * @return BLE_ERROR_NONE if the advertising data was set successfully.
01963      *
01964      * @note Must be implemented in vendor port.
01965      */
01966     virtual ble_error_t setAdvertisingData(
01967         const GapAdvertisingData &advData,
01968         const GapAdvertisingData &scanResponse
01969     ) = 0;
01970 
01971     /**
01972      * Start the advertising procedure.
01973      *
01974      * @param[in] Advertising parameters to use.
01975      *
01976      * @return BLE_ERROR_NONE if the advertising procedure successfully
01977      * started.
01978      *
01979      * @note Must be implemented in vendor port.
01980      */
01981     virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0;
01982 
01983 public:
01984     /**
01985      * Get the current advertising parameters.
01986      *
01987      * @return A reference to the current advertising parameters.
01988      */
01989     GapAdvertisingParams &getAdvertisingParams(void)
01990     {
01991         return _advParams;
01992     }
01993 
01994     /**
01995      * Const alternative to Gap::getAdvertisingParams().
01996      *
01997      * @return A const reference to the current advertising parameters.
01998      */
01999     const GapAdvertisingParams &getAdvertisingParams(void) const
02000     {
02001         return _advParams;
02002     }
02003 
02004     /**
02005      * Set the advertising parameters.
02006      *
02007      * @param[in] newParams The new advertising parameters.
02008      */
02009     void setAdvertisingParams(const GapAdvertisingParams &newParams)
02010     {
02011         _advParams = newParams;
02012     }
02013 
02014     /* Event handlers. */
02015 public:
02016     /**
02017      * Register a callback handling timeout events.
02018      *
02019      * @param[in] callback Event handler being registered.
02020      *
02021      * @note A callback may be unregistered using onTimeout().detach(callback).
02022      *
02023      * @see TimeoutSource_t
02024      */
02025     void onTimeout(TimeoutEventCallback_t  callback)
02026     {
02027         timeoutCallbackChain.add(callback);
02028     }
02029 
02030     /**
02031      * Get the callchain of registered timeout event handlers.
02032      *
02033      * @note To register callbacks, use onTimeout().add(callback).
02034      *
02035      * @note To unregister callbacks, use onTimeout().detach(callback).
02036      *
02037      * @return A reference to the timeout event callbacks chain.
02038      */
02039     TimeoutEventCallbackChain_t & onTimeout()
02040     {
02041         return timeoutCallbackChain;
02042     }
02043 
02044     /**
02045      * Register a callback handling connection events.
02046      *
02047      * @param[in] callback Event handler being registered.
02048      *
02049      * @note A callback may be unregistered using onConnection().detach(callback).
02050      */
02051     void onConnection(ConnectionEventCallback_t  callback)
02052     {
02053         connectionCallChain.add(callback);
02054     }
02055 
02056     /**
02057      * Register a callback handling connection events.
02058      *
02059      * @param[in] tptr Instance used to invoke @p mptr.
02060      * @param[in] mptr Event handler being registered.
02061      *
02062      * @note A callback may be unregistered using onConnection().detach(callback).
02063      */
02064     template<typename T>
02065     void onConnection(T *tptr, void (T::*mptr)(const ConnectionCallbackParams_t*))
02066     {
02067         connectionCallChain.add(tptr, mptr);
02068     }
02069 
02070     /**
02071      * Get the callchain of registered connection event handlers.
02072      *
02073      * @note To register callbacks, use onConnection().add(callback).
02074      *
02075      * @note To unregister callbacks, use onConnection().detach(callback).
02076      *
02077      * @return A reference to the connection event callbacks chain.
02078      */
02079     ConnectionEventCallbackChain_t & onConnection()
02080     {
02081         return connectionCallChain;
02082     }
02083 
02084     /**
02085      * Register a callback handling disconnection events.
02086      *
02087      * @param[in] callback Event handler being registered.
02088      *
02089      * @note A callback may be unregistered using onDisconnection().detach(callback).
02090      */
02091     void onDisconnection(DisconnectionEventCallback_t  callback)
02092     {
02093         disconnectionCallChain.add(callback);
02094     }
02095 
02096     /**
02097      * Register a callback handling disconnection events.
02098      *
02099      * @param[in] tptr Instance used to invoke mptr.
02100      * @param[in] mptr Event handler being registered.
02101      *
02102      * @note A callback may be unregistered using onDisconnection().detach(callback).
02103      */
02104     template<typename T>
02105     void onDisconnection(T *tptr, void (T::*mptr)(const DisconnectionCallbackParams_t*))
02106     {
02107         disconnectionCallChain.add(tptr, mptr);
02108     }
02109 
02110     /**
02111      * Get the callchain of registered disconnection event handlers.
02112      *
02113      * @note To register callbacks use onDisconnection().add(callback).
02114      *
02115      * @note To unregister callbacks use onDisconnection().detach(callback).
02116      *
02117      * @return A reference to the disconnection event callbacks chain.
02118      */
02119     DisconnectionEventCallbackChain_t & onDisconnection()
02120     {
02121         return disconnectionCallChain;
02122     }
02123 
02124     /**
02125      * Set the radio-notification events handler.
02126      *
02127      * Radio Notification is a feature that enables ACTIVE and INACTIVE
02128      * (nACTIVE) signals from the stack that notify the application when the
02129      * radio is in use.
02130      *
02131      * The ACTIVE signal is sent before the radio event starts. The nACTIVE
02132      * signal is sent at the end of the radio event. The application programmer can
02133      * use these signals to synchronize application logic with radio
02134      * activity. For example, the ACTIVE signal can be used to shut off external
02135      * devices, to manage peak current drawn during periods when the radio is on
02136      * or to trigger sensor data collection for transmission in the Radio Event.
02137      *
02138      * @param[in] callback Application handler to be invoked in response to a
02139      * radio ACTIVE/INACTIVE event.
02140      */
02141     void onRadioNotification(void (*callback)(bool param))
02142     {
02143         radioNotificationCallback.attach(callback);
02144     }
02145 
02146     /**
02147      * Set the radio-notification events handler.
02148      *
02149      * @param[in] tptr Instance to be used to invoke mptr.
02150      * @param[in] mptr Application handler to be invoked in response to a
02151      * radio ACTIVE/INACTIVE event.
02152      */
02153     template <typename T>
02154     void onRadioNotification(T *tptr, void (T::*mptr)(bool))
02155     {
02156         radioNotificationCallback.attach(tptr, mptr);
02157     }
02158 
02159     /**
02160      * Register a Gap shutdown event handler.
02161      *
02162      * The handler is called when the Gap instance is about to shut down.
02163      * It is usually issued after a call to BLE::shutdown().
02164      *
02165      * @param[in] callback Shutdown event handler to register.
02166      *
02167      * @note To unregister a shutdown event handler, use
02168      * onShutdown().detach(callback).
02169      */
02170     void onShutdown(const GapShutdownCallback_t & callback)
02171     {
02172         shutdownCallChain.add(callback);
02173     }
02174 
02175     /**
02176      * Register a Gap shutdown event handler.
02177      *
02178      * @param[in] objPtr Instance used to invoke @p memberPtr.
02179      * @param[in] memberPtr Shutdown event handler to register.
02180      */
02181     template <typename T>
02182     void onShutdown(T *objPtr, void (T::*memberPtr)(const Gap *))
02183     {
02184         shutdownCallChain.add(objPtr, memberPtr);
02185     }
02186 
02187     /**
02188      * Access the callchain of shutdown event handler.
02189      *
02190      * @note To register callbacks, use onShutdown().add(callback).
02191      *
02192      * @note To unregister callbacks, use onShutdown().detach(callback).
02193      *
02194      * @return A reference to the shutdown event callback chain.
02195      */
02196     GapShutdownCallbackChain_t & onShutdown()
02197     {
02198         return shutdownCallChain;
02199     }
02200 
02201 public:
02202     /**
02203      * Reset the Gap instance.
02204      *
02205      * Reset process starts by notifying all registered shutdown event handlers
02206      * that the Gap instance is about to be shut down. Then, it clears all Gap state
02207      * of the associated object and then cleans the state present in the vendor
02208      * implementation.
02209      *
02210      * This function is meant to be overridden in the platform-specific
02211      * subclass. Nevertheless, the subclass only resets its
02212      * state and not the data held in Gap members. This is achieved by a
02213      * call to Gap::reset() from the subclass' reset() implementation.
02214      *
02215      * @return BLE_ERROR_NONE on success.
02216      *
02217      * @note Currently, a call to reset() does not reset the advertising and
02218      * scan parameters to default values.
02219      */
02220     virtual ble_error_t reset(void)
02221     {
02222         /* Notify that the instance is about to shut down */
02223         shutdownCallChain.call(this);
02224         shutdownCallChain.clear();
02225 
02226         /* Clear Gap state */
02227         state.advertising = 0;
02228         state.connected   = 0;
02229         connectionCount   = 0;
02230 
02231         /* Clear scanning state */
02232         scanningActive = false;
02233 
02234         /* Clear advertising and scanning data */
02235         _advPayload.clear();
02236         _scanResponse.clear();
02237 
02238         /* Clear callbacks */
02239         timeoutCallbackChain.clear();
02240         connectionCallChain.clear();
02241         disconnectionCallChain.clear();
02242         radioNotificationCallback = NULL;
02243         onAdvertisementReport     = NULL;
02244 
02245         return BLE_ERROR_NONE;
02246     }
02247 
02248 protected:
02249     /**
02250      * Construct a Gap instance.
02251      */
02252     Gap() :
02253         _advParams(),
02254         _advPayload(),
02255         _scanningParams(),
02256         _scanResponse(),
02257         connectionCount(0),
02258         state(),
02259         scanningActive(false),
02260         timeoutCallbackChain(),
02261         radioNotificationCallback(),
02262         onAdvertisementReport(),
02263         connectionCallChain(),
02264         disconnectionCallChain() {
02265         _advPayload.clear();
02266         _scanResponse.clear();
02267     }
02268 
02269     /* Entry points for the underlying stack to report events back to the user. */
02270 public:
02271     /**
02272      * Notify all registered connection event handlers of a connection event.
02273      *
02274      * @important This function is meant to be called from the BLE stack specific
02275      * implementation when a connection event occurs.
02276      *
02277      * @param[in] handle Handle of the new connection.
02278      * @param[in] role Role of this BLE device in the connection.
02279      * @param[in] peerAddrType Address type of the connected peer.
02280      * @param[in] peerAddr Address of the connected peer.
02281      * @param[in] ownAddrType Address type this device uses for this
02282      * connection.
02283      * @param[in] ownAddr Address this device uses for this connection.
02284      * @param[in] connectionParams Parameters of the connection.
02285      */
02286     void processConnectionEvent(
02287         Handle_t handle,
02288         Role_t role,
02289         BLEProtocol::AddressType_t peerAddrType,
02290         const BLEProtocol::AddressBytes_t peerAddr,
02291         BLEProtocol::AddressType_t ownAddrType,
02292         const BLEProtocol::AddressBytes_t ownAddr,
02293         const ConnectionParams_t *connectionParams
02294     ) {
02295         /* Update Gap state */
02296         state.advertising = 0;
02297         state.connected   = 1;
02298         ++connectionCount;
02299 
02300         ConnectionCallbackParams_t callbackParams(
02301             handle,
02302             role,
02303             peerAddrType,
02304             peerAddr,
02305             ownAddrType,
02306             ownAddr,
02307             connectionParams
02308         );
02309         connectionCallChain.call(&callbackParams);
02310     }
02311 
02312     /**
02313      * Notify all registered disconnection event handlers of a disconnection event.
02314      *
02315      * @important This function is meant to be called from the BLE stack specific
02316      * implementation when a disconnection event occurs.
02317      *
02318      * @param[in] handle Handle of the terminated connection.
02319      * @param[in] reason Reason of the disconnection.
02320      */
02321     void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason)
02322     {
02323         /* Update Gap state */
02324         --connectionCount;
02325         if (!connectionCount) {
02326             state.connected = 0;
02327         }
02328 
02329         DisconnectionCallbackParams_t callbackParams(handle, reason);
02330         disconnectionCallChain.call(&callbackParams);
02331     }
02332 
02333     /**
02334      * Forward a received advertising packet to all registered event handlers
02335      * listening for scanned packet events.
02336      *
02337      * @important This function is meant to be called from the BLE stack specific
02338      * implementation when a disconnection event occurs.
02339      *
02340      * @param[in] peerAddr Address of the peer that has emitted the packet.
02341      * @param[in] rssi Value of the RSSI measured for the received packet.
02342      * @param[in] isScanReponse If true, then the packet is a response to a scan
02343      * request.
02344      * @param[in] type Advertising type of the packet.
02345      * @param[in] advertisingDataLen Length of the advertisement data received.
02346      * @param[in] advertisingData Pointer to the advertisement packet's data.
02347      */
02348     void processAdvertisementReport(
02349         const BLEProtocol::AddressBytes_t peerAddr,
02350         int8_t rssi,
02351         bool isScanResponse,
02352         GapAdvertisingParams::AdvertisingType_t type,
02353         uint8_t advertisingDataLen,
02354         const uint8_t *advertisingData
02355     ) {
02356         AdvertisementCallbackParams_t params;
02357         memcpy(params.peerAddr, peerAddr, ADDR_LEN);
02358         params.rssi = rssi;
02359         params.isScanResponse = isScanResponse;
02360         params.type = type;
02361         params.advertisingDataLen = advertisingDataLen;
02362         params.advertisingData = advertisingData;
02363         onAdvertisementReport.call(&params);
02364     }
02365 
02366     /**
02367      * Notify the occurrence of a timeout event to all registered timeout events
02368      * handler.
02369      *
02370      * @important This function is meant to be called from the BLE stack specific
02371      * implementation when a disconnection event occurs.
02372      *
02373      * @param[in] source Source of the timout event.
02374      */
02375     void processTimeoutEvent(TimeoutSource_t source)
02376     {
02377         if (source == TIMEOUT_SRC_ADVERTISING) {
02378             /* Update gap state if the source is an advertising timeout */
02379             state.advertising = 0;
02380         }
02381         if (timeoutCallbackChain) {
02382             timeoutCallbackChain(source);
02383         }
02384     }
02385 
02386 protected:
02387     /**
02388      * Current advertising parameters.
02389      */
02390     GapAdvertisingParams _advParams;
02391 
02392     /**
02393      * Current advertising data.
02394      */
02395     GapAdvertisingData _advPayload;
02396 
02397     /**
02398      * Current scanning parameters.
02399      */
02400     GapScanningParams _scanningParams;
02401 
02402     /**
02403      * Current scan response.
02404      */
02405     GapAdvertisingData _scanResponse;
02406 
02407     /**
02408      * Number of open connections.
02409      */
02410     uint8_t connectionCount;
02411 
02412     /**
02413      * Current GAP state.
02414      */
02415     GapState_t state;
02416 
02417     /**
02418      * Active scanning flag.
02419      */
02420     bool scanningActive;
02421 
02422 protected:
02423     /**
02424      * Callchain containing all registered callback handlers for timeout
02425      * events.
02426      */
02427     TimeoutEventCallbackChain_t  timeoutCallbackChain;
02428 
02429     /**
02430      * The registered callback handler for radio notification events.
02431      */
02432     RadioNotificationEventCallback_t  radioNotificationCallback;
02433 
02434     /**
02435      * The registered callback handler for scanned advertisement packet
02436      * notifications.
02437      */
02438     AdvertisementReportCallback_t  onAdvertisementReport;
02439 
02440     /**
02441      * Callchain containing all registered callback handlers for connection
02442      * events.
02443      */
02444     ConnectionEventCallbackChain_t  connectionCallChain;
02445 
02446     /**
02447      * Callchain containing all registered callback handlers for disconnection
02448      * events.
02449      */
02450     DisconnectionEventCallbackChain_t  disconnectionCallChain;
02451 
02452 private:
02453     /**
02454      * Callchain containing all registered callback handlers for shutdown
02455      * events.
02456      */
02457     GapShutdownCallbackChain_t  shutdownCallChain;
02458 
02459 private:
02460     /* Disallow copy and assignment. */
02461     Gap(const Gap &);
02462     Gap& operator=(const Gap &);
02463 };
02464 
02465 /**
02466  * @}
02467  * @}
02468  */
02469 
02470 #endif // ifndef MBED_BLE_GAP_H__