High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Thu Dec 10 09:15:01 2015 +0000
Revision:
1017:ccb8c0646e55
Parent:
1009:255f75c96eaa
Child:
1020:c8664d12bf10
Synchronized with git rev 12e27cd4
Author: Rohit Grover
Release 2.1.3
=============

* Improvements to CallChainOfFunctionPointerswithContext:
- add a `detach` function to be able to remove callbacks.
- detach function now return true if a function has been detached and
false otherwise.
- add a function call operator.
- use safe-bool idiom. see : http://www.artima.com/cppsource/safebool.html

* Add SafeBool class which allow to easily declare a safe bool operator in
c++03.

* Improvements to FunctionPointerWithContext:
- fix call propagation
- use safe bool idiom

* Add config file for generating Doxygen.

* Setup for onRadioNotification callback does not call initRadioNotification
anymore.

* GapAdvertisementData now handles replacement and appending of data fields
based on type. Some fields can be replaced with new values, and others
require the payload to be appended.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 710:b2e1a2660ec2 1 /* mbed Microcontroller Library
rgrover1 710:b2e1a2660ec2 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 710:b2e1a2660ec2 3 *
rgrover1 710:b2e1a2660ec2 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 710:b2e1a2660ec2 5 * you may not use this file except in compliance with the License.
rgrover1 710:b2e1a2660ec2 6 * You may obtain a copy of the License at
rgrover1 710:b2e1a2660ec2 7 *
rgrover1 710:b2e1a2660ec2 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 710:b2e1a2660ec2 9 *
rgrover1 710:b2e1a2660ec2 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 710:b2e1a2660ec2 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 710:b2e1a2660ec2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 710:b2e1a2660ec2 13 * See the License for the specific language governing permissions and
rgrover1 710:b2e1a2660ec2 14 * limitations under the License.
rgrover1 710:b2e1a2660ec2 15 */
rgrover1 710:b2e1a2660ec2 16
rgrover1 710:b2e1a2660ec2 17 #ifndef __GAP_H__
rgrover1 710:b2e1a2660ec2 18 #define __GAP_H__
rgrover1 710:b2e1a2660ec2 19
rgrover1 710:b2e1a2660ec2 20 #include "GapAdvertisingData.h"
rgrover1 710:b2e1a2660ec2 21 #include "GapAdvertisingParams.h"
rgrover1 710:b2e1a2660ec2 22 #include "GapScanningParams.h"
rgrover1 710:b2e1a2660ec2 23 #include "GapEvents.h"
rgrover1 829:9072de50087b 24 #include "CallChainOfFunctionPointersWithContext.h"
rgrover1 710:b2e1a2660ec2 25 #include "FunctionPointerWithContext.h"
rgrover1 710:b2e1a2660ec2 26
rgrover1 993:4d62b7967c11 27 /* Forward declarations for classes that will only be used for pointers or references in the following. */
rgrover1 710:b2e1a2660ec2 28 class GapAdvertisingParams;
rgrover1 710:b2e1a2660ec2 29 class GapScanningParams;
rgrover1 710:b2e1a2660ec2 30 class GapAdvertisingData;
rgrover1 710:b2e1a2660ec2 31
rgrover1 710:b2e1a2660ec2 32 class Gap {
rgrover1 710:b2e1a2660ec2 33 public:
rgrover1 710:b2e1a2660ec2 34 enum AddressType_t {
rgrover1 710:b2e1a2660ec2 35 ADDR_TYPE_PUBLIC = 0,
rgrover1 710:b2e1a2660ec2 36 ADDR_TYPE_RANDOM_STATIC,
rgrover1 710:b2e1a2660ec2 37 ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
rgrover1 710:b2e1a2660ec2 38 ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
rgrover1 710:b2e1a2660ec2 39 };
rgrover1 993:4d62b7967c11 40 typedef enum AddressType_t addr_type_t; /* @Note: Deprecated. Use AddressType_t instead. */
rgrover1 710:b2e1a2660ec2 41
rgrover1 710:b2e1a2660ec2 42 static const unsigned ADDR_LEN = 6;
rgrover1 710:b2e1a2660ec2 43 typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */
rgrover1 993:4d62b7967c11 44 typedef Address_t address_t; /* @Note: Deprecated. Use Address_t instead. */
rgrover1 710:b2e1a2660ec2 45
rgrover1 710:b2e1a2660ec2 46 enum TimeoutSource_t {
rgrover1 710:b2e1a2660ec2 47 TIMEOUT_SRC_ADVERTISING = 0x00, /**< Advertising timeout. */
rgrover1 710:b2e1a2660ec2 48 TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */
rgrover1 710:b2e1a2660ec2 49 TIMEOUT_SRC_SCAN = 0x02, /**< Scanning timeout. */
rgrover1 710:b2e1a2660ec2 50 TIMEOUT_SRC_CONN = 0x03, /**< Connection timeout. */
rgrover1 710:b2e1a2660ec2 51 };
rgrover1 710:b2e1a2660ec2 52
rgrover1 710:b2e1a2660ec2 53 /**
rgrover1 710:b2e1a2660ec2 54 * Enumeration for disconnection reasons. The values for these reasons are
rgrover1 993:4d62b7967c11 55 * derived from Nordic's implementation, but the reasons are meant to be
rgrover1 993:4d62b7967c11 56 * independent of the transport. If you are returned a reason that is not
rgrover1 993:4d62b7967c11 57 * covered by this enumeration, please refer to the underlying
rgrover1 710:b2e1a2660ec2 58 * transport library.
rgrover1 710:b2e1a2660ec2 59 */
rgrover1 710:b2e1a2660ec2 60 enum DisconnectionReason_t {
rgrover1 710:b2e1a2660ec2 61 CONNECTION_TIMEOUT = 0x08,
rgrover1 710:b2e1a2660ec2 62 REMOTE_USER_TERMINATED_CONNECTION = 0x13,
rgrover1 993:4d62b7967c11 63 REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote device terminated connection due to low resources.*/
rgrover1 993:4d62b7967c11 64 REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote device terminated connection due to power off. */
rgrover1 710:b2e1a2660ec2 65 LOCAL_HOST_TERMINATED_CONNECTION = 0x16,
rgrover1 710:b2e1a2660ec2 66 CONN_INTERVAL_UNACCEPTABLE = 0x3B,
rgrover1 710:b2e1a2660ec2 67 };
rgrover1 710:b2e1a2660ec2 68
rgrover1 993:4d62b7967c11 69 /* Describes the current state of the device (more than one bit can be set). */
rgrover1 710:b2e1a2660ec2 70 struct GapState_t {
rgrover1 993:4d62b7967c11 71 unsigned advertising : 1; /**< Peripheral is currently advertising. */
rgrover1 993:4d62b7967c11 72 unsigned connected : 1; /**< Peripheral is connected to a central. */
rgrover1 710:b2e1a2660ec2 73 };
rgrover1 710:b2e1a2660ec2 74
rgrover1 710:b2e1a2660ec2 75 typedef uint16_t Handle_t; /* Type for connection handle. */
rgrover1 710:b2e1a2660ec2 76
rgrover1 710:b2e1a2660ec2 77 typedef struct {
rgrover1 710:b2e1a2660ec2 78 uint16_t minConnectionInterval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
rgrover1 710:b2e1a2660ec2 79 uint16_t maxConnectionInterval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
rgrover1 710:b2e1a2660ec2 80 uint16_t slaveLatency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
rgrover1 710:b2e1a2660ec2 81 uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
rgrover1 710:b2e1a2660ec2 82 } ConnectionParams_t;
rgrover1 710:b2e1a2660ec2 83
rgrover1 710:b2e1a2660ec2 84 enum Role_t {
rgrover1 710:b2e1a2660ec2 85 PERIPHERAL = 0x1, /**< Peripheral Role. */
rgrover1 710:b2e1a2660ec2 86 CENTRAL = 0x2, /**< Central Role. */
rgrover1 710:b2e1a2660ec2 87 };
rgrover1 710:b2e1a2660ec2 88
rgrover1 710:b2e1a2660ec2 89 struct AdvertisementCallbackParams_t {
rgrover1 710:b2e1a2660ec2 90 Address_t peerAddr;
rgrover1 710:b2e1a2660ec2 91 int8_t rssi;
rgrover1 710:b2e1a2660ec2 92 bool isScanResponse;
rgrover1 710:b2e1a2660ec2 93 GapAdvertisingParams::AdvertisingType_t type;
rgrover1 710:b2e1a2660ec2 94 uint8_t advertisingDataLen;
rgrover1 710:b2e1a2660ec2 95 const uint8_t *advertisingData;
rgrover1 710:b2e1a2660ec2 96 };
rgrover1 710:b2e1a2660ec2 97 typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t;
rgrover1 710:b2e1a2660ec2 98
rgrover1 710:b2e1a2660ec2 99 struct ConnectionCallbackParams_t {
rgrover1 710:b2e1a2660ec2 100 Handle_t handle;
rgrover1 710:b2e1a2660ec2 101 Role_t role;
rgrover1 710:b2e1a2660ec2 102 AddressType_t peerAddrType;
rgrover1 710:b2e1a2660ec2 103 Address_t peerAddr;
rgrover1 710:b2e1a2660ec2 104 AddressType_t ownAddrType;
rgrover1 710:b2e1a2660ec2 105 Address_t ownAddr;
rgrover1 710:b2e1a2660ec2 106 const ConnectionParams_t *connectionParams;
rgrover1 710:b2e1a2660ec2 107
rgrover1 710:b2e1a2660ec2 108 ConnectionCallbackParams_t(Handle_t handleIn,
rgrover1 710:b2e1a2660ec2 109 Role_t roleIn,
rgrover1 710:b2e1a2660ec2 110 AddressType_t peerAddrTypeIn,
rgrover1 710:b2e1a2660ec2 111 const uint8_t *peerAddrIn,
rgrover1 710:b2e1a2660ec2 112 AddressType_t ownAddrTypeIn,
rgrover1 710:b2e1a2660ec2 113 const uint8_t *ownAddrIn,
rgrover1 710:b2e1a2660ec2 114 const ConnectionParams_t *connectionParamsIn) :
rgrover1 710:b2e1a2660ec2 115 handle(handleIn),
rgrover1 710:b2e1a2660ec2 116 role(roleIn),
rgrover1 710:b2e1a2660ec2 117 peerAddrType(peerAddrTypeIn),
rgrover1 710:b2e1a2660ec2 118 peerAddr(),
rgrover1 710:b2e1a2660ec2 119 ownAddrType(ownAddrTypeIn),
rgrover1 710:b2e1a2660ec2 120 ownAddr(),
rgrover1 710:b2e1a2660ec2 121 connectionParams(connectionParamsIn) {
rgrover1 710:b2e1a2660ec2 122 memcpy(peerAddr, peerAddrIn, ADDR_LEN);
rgrover1 710:b2e1a2660ec2 123 memcpy(ownAddr, ownAddrIn, ADDR_LEN);
rgrover1 710:b2e1a2660ec2 124 }
rgrover1 710:b2e1a2660ec2 125 };
rgrover1 710:b2e1a2660ec2 126
rgrover1 829:9072de50087b 127 struct DisconnectionCallbackParams_t {
rgrover1 829:9072de50087b 128 Handle_t handle;
rgrover1 829:9072de50087b 129 DisconnectionReason_t reason;
rgrover1 829:9072de50087b 130
rgrover1 829:9072de50087b 131 DisconnectionCallbackParams_t(Handle_t handleIn,
rgrover1 829:9072de50087b 132 DisconnectionReason_t reasonIn) :
rgrover1 829:9072de50087b 133 handle(handleIn),
rgrover1 829:9072de50087b 134 reason(reasonIn)
rgrover1 829:9072de50087b 135 {}
rgrover1 829:9072de50087b 136 };
rgrover1 829:9072de50087b 137
rgrover1 710:b2e1a2660ec2 138 static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */
rgrover1 710:b2e1a2660ec2 139 static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) {
rgrover1 710:b2e1a2660ec2 140 return (durationInMillis * 1000) / UNIT_1_25_MS;
rgrover1 710:b2e1a2660ec2 141 }
rgrover1 766:03f1a26f132f 142
rgrover1 993:4d62b7967c11 143 typedef FunctionPointerWithContext<TimeoutSource_t> TimeoutEventCallback_t;
rgrover1 993:4d62b7967c11 144 typedef CallChainOfFunctionPointersWithContext<TimeoutSource_t> TimeoutEventCallbackChain_t;
rgrover1 710:b2e1a2660ec2 145
rgrover1 993:4d62b7967c11 146 typedef FunctionPointerWithContext<const ConnectionCallbackParams_t *> ConnectionEventCallback_t;
rgrover1 993:4d62b7967c11 147 typedef CallChainOfFunctionPointersWithContext<const ConnectionCallbackParams_t *> ConnectionEventCallbackChain_t;
rgrover1 993:4d62b7967c11 148
rgrover1 993:4d62b7967c11 149 typedef FunctionPointerWithContext<const DisconnectionCallbackParams_t*> DisconnectionEventCallback_t;
rgrover1 1017:ccb8c0646e55 150 typedef CallChainOfFunctionPointersWithContext<const DisconnectionCallbackParams_t*> DisconnectionEventCallbackChain_t;
rgrover1 993:4d62b7967c11 151
rgrover1 753:0f60274cd3ad 152 typedef FunctionPointerWithContext<bool> RadioNotificationEventCallback_t;
rgrover1 710:b2e1a2660ec2 153
rgrover1 710:b2e1a2660ec2 154 /*
rgrover1 710:b2e1a2660ec2 155 * The following functions are meant to be overridden in the platform-specific sub-class.
rgrover1 710:b2e1a2660ec2 156 */
rgrover1 710:b2e1a2660ec2 157 public:
rgrover1 710:b2e1a2660ec2 158 /**
rgrover1 710:b2e1a2660ec2 159 * Set the BTLE MAC address and type. Please note that the address format is
rgrover1 993:4d62b7967c11 160 * least significant byte first (LSB). Please refer to Address_t.
rgrover1 710:b2e1a2660ec2 161 *
rgrover1 710:b2e1a2660ec2 162 * @return BLE_ERROR_NONE on success.
rgrover1 710:b2e1a2660ec2 163 */
rgrover1 710:b2e1a2660ec2 164 virtual ble_error_t setAddress(AddressType_t type, const Address_t address) {
rgrover1 734:4872b70437ce 165 /* avoid compiler warnings about unused variables */
rgrover1 734:4872b70437ce 166 (void)type;
rgrover1 734:4872b70437ce 167 (void)address;
rgrover1 734:4872b70437ce 168
rgrover1 728:997ba5e7b3b6 169 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 170 }
rgrover1 710:b2e1a2660ec2 171
rgrover1 710:b2e1a2660ec2 172 /**
rgrover1 710:b2e1a2660ec2 173 * Fetch the BTLE MAC address and type.
rgrover1 710:b2e1a2660ec2 174 *
rgrover1 710:b2e1a2660ec2 175 * @return BLE_ERROR_NONE on success.
rgrover1 710:b2e1a2660ec2 176 */
rgrover1 710:b2e1a2660ec2 177 virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) {
rgrover1 993:4d62b7967c11 178 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 179 (void)typeP;
rgrover1 734:4872b70437ce 180 (void)address;
rgrover1 734:4872b70437ce 181
rgrover1 728:997ba5e7b3b6 182 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 183 }
rgrover1 710:b2e1a2660ec2 184
rgrover1 710:b2e1a2660ec2 185 /**
rgrover1 710:b2e1a2660ec2 186 * @return Minimum Advertising interval in milliseconds.
rgrover1 710:b2e1a2660ec2 187 */
rgrover1 710:b2e1a2660ec2 188 virtual uint16_t getMinAdvertisingInterval(void) const {
rgrover1 742:861ed7eb186d 189 return 0; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 190 }
rgrover1 710:b2e1a2660ec2 191
rgrover1 710:b2e1a2660ec2 192 /**
rgrover1 710:b2e1a2660ec2 193 * @return Minimum Advertising interval in milliseconds for non-connectible mode.
rgrover1 710:b2e1a2660ec2 194 */
rgrover1 710:b2e1a2660ec2 195 virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {
rgrover1 742:861ed7eb186d 196 return 0; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 197 }
rgrover1 710:b2e1a2660ec2 198
rgrover1 710:b2e1a2660ec2 199 /**
rgrover1 710:b2e1a2660ec2 200 * @return Maximum Advertising interval in milliseconds.
rgrover1 710:b2e1a2660ec2 201 */
rgrover1 710:b2e1a2660ec2 202 virtual uint16_t getMaxAdvertisingInterval(void) const {
rgrover1 742:861ed7eb186d 203 return 0xFFFF; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 204 }
rgrover1 710:b2e1a2660ec2 205
rgrover1 710:b2e1a2660ec2 206 virtual ble_error_t stopAdvertising(void) {
rgrover1 728:997ba5e7b3b6 207 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 208 }
rgrover1 710:b2e1a2660ec2 209
rgrover1 710:b2e1a2660ec2 210 /**
rgrover1 710:b2e1a2660ec2 211 * Stop scanning. The current scanning parameters remain in effect.
rgrover1 710:b2e1a2660ec2 212 *
rgrover1 710:b2e1a2660ec2 213 * @retval BLE_ERROR_NONE if successfully stopped scanning procedure.
rgrover1 710:b2e1a2660ec2 214 */
rgrover1 710:b2e1a2660ec2 215 virtual ble_error_t stopScan() {
rgrover1 728:997ba5e7b3b6 216 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 217 }
rgrover1 710:b2e1a2660ec2 218
rgrover1 710:b2e1a2660ec2 219 /**
rgrover1 710:b2e1a2660ec2 220 * Create a connection (GAP Link Establishment).
rgrover1 710:b2e1a2660ec2 221 *
rgrover1 710:b2e1a2660ec2 222 * @param peerAddr
rgrover1 710:b2e1a2660ec2 223 * 48-bit address, LSB format.
rgrover1 710:b2e1a2660ec2 224 * @param peerAddrType
rgrover1 710:b2e1a2660ec2 225 * Address type of the peer.
rgrover1 710:b2e1a2660ec2 226 * @param connectionParams
rgrover1 710:b2e1a2660ec2 227 * Connection parameters.
rgrover1 710:b2e1a2660ec2 228 * @param scanParams
rgrover1 710:b2e1a2660ec2 229 * Paramters to be used while scanning for the peer.
rgrover1 710:b2e1a2660ec2 230 * @return BLE_ERROR_NONE if connection establishment procedure is started
rgrover1 829:9072de50087b 231 * successfully. The connectionCallChain (if set) will be invoked upon
rgrover1 710:b2e1a2660ec2 232 * a connection event.
rgrover1 710:b2e1a2660ec2 233 */
rgrover1 710:b2e1a2660ec2 234 virtual ble_error_t connect(const Address_t peerAddr,
rgrover1 710:b2e1a2660ec2 235 Gap::AddressType_t peerAddrType,
rgrover1 710:b2e1a2660ec2 236 const ConnectionParams_t *connectionParams,
rgrover1 710:b2e1a2660ec2 237 const GapScanningParams *scanParams) {
rgrover1 993:4d62b7967c11 238 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 239 (void)peerAddr;
rgrover1 734:4872b70437ce 240 (void)peerAddrType;
rgrover1 734:4872b70437ce 241 (void)connectionParams;
rgrover1 734:4872b70437ce 242 (void)scanParams;
rgrover1 734:4872b70437ce 243
rgrover1 728:997ba5e7b3b6 244 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 245 }
rgrover1 710:b2e1a2660ec2 246
rgrover1 710:b2e1a2660ec2 247 /**
rgrover1 710:b2e1a2660ec2 248 * This call initiates the disconnection procedure, and its completion will
rgrover1 710:b2e1a2660ec2 249 * be communicated to the application with an invocation of the
rgrover1 710:b2e1a2660ec2 250 * disconnectionCallback.
rgrover1 710:b2e1a2660ec2 251 *
rgrover1 710:b2e1a2660ec2 252 * @param reason
rgrover1 993:4d62b7967c11 253 * The reason for disconnection; to be sent back to the peer.
rgrover1 710:b2e1a2660ec2 254 */
rgrover1 710:b2e1a2660ec2 255 virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) {
rgrover1 734:4872b70437ce 256 /* avoid compiler warnings about unused variables */
rgrover1 734:4872b70437ce 257 (void)connectionHandle;
rgrover1 734:4872b70437ce 258 (void)reason;
rgrover1 734:4872b70437ce 259
rgrover1 728:997ba5e7b3b6 260 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 261 }
rgrover1 710:b2e1a2660ec2 262
rgrover1 710:b2e1a2660ec2 263 /**
rgrover1 710:b2e1a2660ec2 264 * This call initiates the disconnection procedure, and its completion will
rgrover1 710:b2e1a2660ec2 265 * be communicated to the application with an invocation of the
rgrover1 710:b2e1a2660ec2 266 * disconnectionCallback.
rgrover1 710:b2e1a2660ec2 267 *
rgrover1 710:b2e1a2660ec2 268 * @param reason
rgrover1 993:4d62b7967c11 269 * The reason for disconnection; to be sent back to the peer.
rgrover1 710:b2e1a2660ec2 270 *
rgrover1 993:4d62b7967c11 271 * @note: This version of disconnect() doesn't take a connection handle. It
rgrover1 993:4d62b7967c11 272 * works reliably only for stacks that are limited to a single
rgrover1 710:b2e1a2660ec2 273 * connection. This API should be considered *deprecated* in favour of the
rgrover1 993:4d62b7967c11 274 * alternative, which takes a connection handle. It will be dropped in the future.
rgrover1 710:b2e1a2660ec2 275 */
rgrover1 710:b2e1a2660ec2 276 virtual ble_error_t disconnect(DisconnectionReason_t reason) {
rgrover1 993:4d62b7967c11 277 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 278 (void)reason;
rgrover1 734:4872b70437ce 279
rgrover1 728:997ba5e7b3b6 280 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 281 }
rgrover1 710:b2e1a2660ec2 282
rgrover1 710:b2e1a2660ec2 283 /**
rgrover1 710:b2e1a2660ec2 284 * Get the GAP peripheral preferred connection parameters. These are the
rgrover1 710:b2e1a2660ec2 285 * defaults that the peripheral would like to have in a connection. The
rgrover1 710:b2e1a2660ec2 286 * choice of the connection parameters is eventually up to the central.
rgrover1 710:b2e1a2660ec2 287 *
rgrover1 710:b2e1a2660ec2 288 * @param[out] params
rgrover1 710:b2e1a2660ec2 289 * The structure where the parameters will be stored. Memory
rgrover1 710:b2e1a2660ec2 290 * for this is owned by the caller.
rgrover1 710:b2e1a2660ec2 291 *
rgrover1 710:b2e1a2660ec2 292 * @return BLE_ERROR_NONE if the parameters were successfully filled into
rgrover1 710:b2e1a2660ec2 293 * the given structure pointed to by params.
rgrover1 710:b2e1a2660ec2 294 */
rgrover1 710:b2e1a2660ec2 295 virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) {
rgrover1 993:4d62b7967c11 296 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 297 (void)params;
rgrover1 734:4872b70437ce 298
rgrover1 728:997ba5e7b3b6 299 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 300 }
rgrover1 710:b2e1a2660ec2 301
rgrover1 710:b2e1a2660ec2 302 /**
rgrover1 710:b2e1a2660ec2 303 * Set the GAP peripheral preferred connection parameters. These are the
rgrover1 710:b2e1a2660ec2 304 * defaults that the peripheral would like to have in a connection. The
rgrover1 710:b2e1a2660ec2 305 * choice of the connection parameters is eventually up to the central.
rgrover1 710:b2e1a2660ec2 306 *
rgrover1 710:b2e1a2660ec2 307 * @param[in] params
rgrover1 710:b2e1a2660ec2 308 * The structure containing the desired parameters.
rgrover1 710:b2e1a2660ec2 309 */
rgrover1 710:b2e1a2660ec2 310 virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) {
rgrover1 993:4d62b7967c11 311 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 312 (void)params;
rgrover1 734:4872b70437ce 313
rgrover1 728:997ba5e7b3b6 314 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 315 }
rgrover1 710:b2e1a2660ec2 316
rgrover1 710:b2e1a2660ec2 317 /**
rgrover1 816:2b4f0ef8c06e 318 * Update connection parameters.
rgrover1 993:4d62b7967c11 319 * In the central role this will initiate a Link Layer connection parameter update procedure.
rgrover1 993:4d62b7967c11 320 * In the peripheral role, this will send the corresponding L2CAP request and wait for
rgrover1 816:2b4f0ef8c06e 321 * the central to perform the procedure.
rgrover1 816:2b4f0ef8c06e 322 *
rgrover1 710:b2e1a2660ec2 323 * @param[in] handle
rgrover1 993:4d62b7967c11 324 * Connection Handle.
rgrover1 710:b2e1a2660ec2 325 * @param[in] params
rgrover1 710:b2e1a2660ec2 326 * Pointer to desired connection parameters. If NULL is provided on a peripheral role,
rgrover1 710:b2e1a2660ec2 327 * the parameters in the PPCP characteristic of the GAP service will be used instead.
rgrover1 710:b2e1a2660ec2 328 */
rgrover1 710:b2e1a2660ec2 329 virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) {
rgrover1 734:4872b70437ce 330 /* avoid compiler warnings about unused variables */
rgrover1 734:4872b70437ce 331 (void)handle;
rgrover1 734:4872b70437ce 332 (void)params;
rgrover1 734:4872b70437ce 333
rgrover1 728:997ba5e7b3b6 334 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 335 }
rgrover1 710:b2e1a2660ec2 336
rgrover1 710:b2e1a2660ec2 337 /**
rgrover1 710:b2e1a2660ec2 338 * Set the device name characteristic in the GAP service.
rgrover1 710:b2e1a2660ec2 339 * @param[in] deviceName
rgrover1 710:b2e1a2660ec2 340 * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string.
rgrover1 710:b2e1a2660ec2 341 */
rgrover1 710:b2e1a2660ec2 342 virtual ble_error_t setDeviceName(const uint8_t *deviceName) {
rgrover1 993:4d62b7967c11 343 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 344 (void)deviceName;
rgrover1 734:4872b70437ce 345
rgrover1 728:997ba5e7b3b6 346 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 347 }
rgrover1 710:b2e1a2660ec2 348
rgrover1 710:b2e1a2660ec2 349 /**
rgrover1 710:b2e1a2660ec2 350 * Get the value of the device name characteristic in the GAP service.
rgrover1 710:b2e1a2660ec2 351 * @param[out] deviceName
rgrover1 710:b2e1a2660ec2 352 * Pointer to an empty buffer where the UTF-8 *non NULL-
rgrover1 710:b2e1a2660ec2 353 * terminated* string will be placed. Set this
rgrover1 710:b2e1a2660ec2 354 * value to NULL in order to obtain the deviceName-length
rgrover1 710:b2e1a2660ec2 355 * from the 'length' parameter.
rgrover1 710:b2e1a2660ec2 356 *
rgrover1 710:b2e1a2660ec2 357 * @param[in/out] lengthP
rgrover1 710:b2e1a2660ec2 358 * (on input) Length of the buffer pointed to by deviceName;
rgrover1 710:b2e1a2660ec2 359 * (on output) the complete device name length (without the
rgrover1 710:b2e1a2660ec2 360 * null terminator).
rgrover1 710:b2e1a2660ec2 361 *
rgrover1 710:b2e1a2660ec2 362 * @note If the device name is longer than the size of the supplied buffer,
rgrover1 710:b2e1a2660ec2 363 * length will return the complete device name length, and not the
rgrover1 710:b2e1a2660ec2 364 * number of bytes actually returned in deviceName. The application may
rgrover1 710:b2e1a2660ec2 365 * use this information to retry with a suitable buffer size.
rgrover1 710:b2e1a2660ec2 366 */
rgrover1 710:b2e1a2660ec2 367 virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) {
rgrover1 734:4872b70437ce 368 /* avoid compiler warnings about unused variables */
rgrover1 734:4872b70437ce 369 (void)deviceName;
rgrover1 734:4872b70437ce 370 (void)lengthP;
rgrover1 734:4872b70437ce 371
rgrover1 728:997ba5e7b3b6 372 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 373 }
rgrover1 710:b2e1a2660ec2 374
rgrover1 710:b2e1a2660ec2 375 /**
rgrover1 710:b2e1a2660ec2 376 * Set the appearance characteristic in the GAP service.
rgrover1 710:b2e1a2660ec2 377 * @param[in] appearance
rgrover1 710:b2e1a2660ec2 378 * The new value for the device-appearance.
rgrover1 710:b2e1a2660ec2 379 */
rgrover1 710:b2e1a2660ec2 380 virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) {
rgrover1 993:4d62b7967c11 381 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 382 (void)appearance;
rgrover1 734:4872b70437ce 383
rgrover1 728:997ba5e7b3b6 384 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 385 }
rgrover1 710:b2e1a2660ec2 386
rgrover1 710:b2e1a2660ec2 387 /**
rgrover1 710:b2e1a2660ec2 388 * Get the appearance characteristic in the GAP service.
rgrover1 710:b2e1a2660ec2 389 * @param[out] appearance
rgrover1 710:b2e1a2660ec2 390 * The new value for the device-appearance.
rgrover1 710:b2e1a2660ec2 391 */
rgrover1 710:b2e1a2660ec2 392 virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) {
rgrover1 993:4d62b7967c11 393 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 394 (void)appearanceP;
rgrover1 734:4872b70437ce 395
rgrover1 728:997ba5e7b3b6 396 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 397 }
rgrover1 710:b2e1a2660ec2 398
rgrover1 710:b2e1a2660ec2 399 /**
rgrover1 710:b2e1a2660ec2 400 * Set the radio's transmit power.
rgrover1 710:b2e1a2660ec2 401 * @param[in] txPower Radio transmit power in dBm.
rgrover1 710:b2e1a2660ec2 402 */
rgrover1 710:b2e1a2660ec2 403 virtual ble_error_t setTxPower(int8_t txPower) {
rgrover1 993:4d62b7967c11 404 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 405 (void)txPower;
rgrover1 734:4872b70437ce 406
rgrover1 728:997ba5e7b3b6 407 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 408 }
rgrover1 710:b2e1a2660ec2 409
rgrover1 710:b2e1a2660ec2 410 /**
rgrover1 710:b2e1a2660ec2 411 * Query the underlying stack for permitted arguments for setTxPower().
rgrover1 710:b2e1a2660ec2 412 *
rgrover1 710:b2e1a2660ec2 413 * @param[out] valueArrayPP
rgrover1 710:b2e1a2660ec2 414 * Out parameter to receive the immutable array of Tx values.
rgrover1 710:b2e1a2660ec2 415 * @param[out] countP
rgrover1 710:b2e1a2660ec2 416 * Out parameter to receive the array's size.
rgrover1 710:b2e1a2660ec2 417 */
rgrover1 710:b2e1a2660ec2 418 virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
rgrover1 993:4d62b7967c11 419 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 420 (void)valueArrayPP;
rgrover1 734:4872b70437ce 421 (void)countP;
rgrover1 734:4872b70437ce 422
rgrover1 742:861ed7eb186d 423 *countP = 0; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 424 }
rgrover1 710:b2e1a2660ec2 425
rgrover1 710:b2e1a2660ec2 426 protected:
rgrover1 710:b2e1a2660ec2 427 /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */
rgrover1 710:b2e1a2660ec2 428 virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) {
rgrover1 772:b6d27ab66c94 429 (void)scanningParams;
rgrover1 728:997ba5e7b3b6 430 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 431 }
rgrover1 710:b2e1a2660ec2 432
rgrover1 710:b2e1a2660ec2 433 /*
rgrover1 710:b2e1a2660ec2 434 * APIs with non-virtual implementations.
rgrover1 710:b2e1a2660ec2 435 */
rgrover1 710:b2e1a2660ec2 436 public:
rgrover1 710:b2e1a2660ec2 437 /**
rgrover1 993:4d62b7967c11 438 * Returns the current GAP state of the device using a bitmask that
rgrover1 993:4d62b7967c11 439 * describes whether the device is advertising or connected.
rgrover1 710:b2e1a2660ec2 440 */
rgrover1 710:b2e1a2660ec2 441 GapState_t getState(void) const {
rgrover1 710:b2e1a2660ec2 442 return state;
rgrover1 710:b2e1a2660ec2 443 }
rgrover1 710:b2e1a2660ec2 444
rgrover1 710:b2e1a2660ec2 445 /**
rgrover1 710:b2e1a2660ec2 446 * Set the GAP advertising mode to use for this device.
rgrover1 710:b2e1a2660ec2 447 */
rgrover1 710:b2e1a2660ec2 448 void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) {
rgrover1 710:b2e1a2660ec2 449 _advParams.setAdvertisingType(advType);
rgrover1 710:b2e1a2660ec2 450 }
rgrover1 710:b2e1a2660ec2 451
rgrover1 710:b2e1a2660ec2 452 /**
rgrover1 710:b2e1a2660ec2 453 * @param[in] interval
rgrover1 710:b2e1a2660ec2 454 * Advertising interval in units of milliseconds. Advertising
rgrover1 710:b2e1a2660ec2 455 * is disabled if interval is 0. If interval is smaller than
rgrover1 710:b2e1a2660ec2 456 * the minimum supported value, then the minimum supported
rgrover1 710:b2e1a2660ec2 457 * value is used instead. This minimum value can be discovered
rgrover1 710:b2e1a2660ec2 458 * using getMinAdvertisingInterval().
rgrover1 710:b2e1a2660ec2 459 *
rgrover1 710:b2e1a2660ec2 460 * This field must be set to 0 if connectionMode is equal
rgrover1 710:b2e1a2660ec2 461 * to ADV_CONNECTABLE_DIRECTED.
rgrover1 710:b2e1a2660ec2 462 *
rgrover1 710:b2e1a2660ec2 463 * @note: Decreasing this value will allow central devices to detect a
rgrover1 993:4d62b7967c11 464 * peripheral faster, at the expense of more power being used by the radio
rgrover1 710:b2e1a2660ec2 465 * due to the higher data transmit rate.
rgrover1 710:b2e1a2660ec2 466 *
rgrover1 710:b2e1a2660ec2 467 * @note: This API is now *deprecated* and will be dropped in the future.
rgrover1 710:b2e1a2660ec2 468 * You should use the parallel API from Gap directly. A former call to
rgrover1 710:b2e1a2660ec2 469 * ble.setAdvertisingInterval(...) should now be achieved using
rgrover1 710:b2e1a2660ec2 470 * ble.gap().setAdvertisingInterval(...).
rgrover1 710:b2e1a2660ec2 471 *
rgrover1 710:b2e1a2660ec2 472 * @Note: [WARNING] This API previously used 0.625ms as the unit for its
rgrover1 710:b2e1a2660ec2 473 * 'interval' argument. That required an explicit conversion from
rgrover1 710:b2e1a2660ec2 474 * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is
rgrover1 710:b2e1a2660ec2 475 * no longer required as the new units are milliseconds. Any application
rgrover1 993:4d62b7967c11 476 * code depending on the old semantics needs to be updated accordingly.
rgrover1 710:b2e1a2660ec2 477 */
rgrover1 710:b2e1a2660ec2 478 void setAdvertisingInterval(uint16_t interval) {
rgrover1 710:b2e1a2660ec2 479 if (interval == 0) {
rgrover1 710:b2e1a2660ec2 480 stopAdvertising();
rgrover1 710:b2e1a2660ec2 481 } else if (interval < getMinAdvertisingInterval()) {
rgrover1 710:b2e1a2660ec2 482 interval = getMinAdvertisingInterval();
rgrover1 710:b2e1a2660ec2 483 }
rgrover1 786:d6d7087d8377 484 _advParams.setInterval(interval);
rgrover1 710:b2e1a2660ec2 485 }
rgrover1 710:b2e1a2660ec2 486
rgrover1 710:b2e1a2660ec2 487 /**
rgrover1 710:b2e1a2660ec2 488 * @param[in] timeout
rgrover1 710:b2e1a2660ec2 489 * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1
rgrover1 710:b2e1a2660ec2 490 * and 16383). Use 0 to disable the advertising timeout.
rgrover1 710:b2e1a2660ec2 491 */
rgrover1 710:b2e1a2660ec2 492 void setAdvertisingTimeout(uint16_t timeout) {
rgrover1 710:b2e1a2660ec2 493 _advParams.setTimeout(timeout);
rgrover1 710:b2e1a2660ec2 494 }
rgrover1 710:b2e1a2660ec2 495
rgrover1 710:b2e1a2660ec2 496 /**
rgrover1 710:b2e1a2660ec2 497 * Start advertising.
rgrover1 710:b2e1a2660ec2 498 */
rgrover1 710:b2e1a2660ec2 499 ble_error_t startAdvertising(void) {
rgrover1 993:4d62b7967c11 500 setAdvertisingData(); /* Update the underlying stack. */
rgrover1 710:b2e1a2660ec2 501 return startAdvertising(_advParams);
rgrover1 710:b2e1a2660ec2 502 }
rgrover1 710:b2e1a2660ec2 503
rgrover1 710:b2e1a2660ec2 504 /**
rgrover1 710:b2e1a2660ec2 505 * Reset any advertising payload prepared from prior calls to
rgrover1 710:b2e1a2660ec2 506 * accumulateAdvertisingPayload(). This automatically propagates the re-
rgrover1 993:4d62b7967c11 507 * initialized advertising payload to the underlying stack.
rgrover1 710:b2e1a2660ec2 508 */
rgrover1 710:b2e1a2660ec2 509 void clearAdvertisingPayload(void) {
rgrover1 710:b2e1a2660ec2 510 _advPayload.clear();
rgrover1 710:b2e1a2660ec2 511 setAdvertisingData();
rgrover1 710:b2e1a2660ec2 512 }
rgrover1 710:b2e1a2660ec2 513
rgrover1 710:b2e1a2660ec2 514 /**
rgrover1 710:b2e1a2660ec2 515 * Accumulate an AD structure in the advertising payload. Please note that
rgrover1 710:b2e1a2660ec2 516 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
rgrover1 993:4d62b7967c11 517 * as an additional 31 bytes if the advertising payload is too
rgrover1 710:b2e1a2660ec2 518 * small.
rgrover1 710:b2e1a2660ec2 519 *
rgrover1 710:b2e1a2660ec2 520 * @param[in] flags
rgrover1 710:b2e1a2660ec2 521 * The flags to be added. Please refer to
rgrover1 710:b2e1a2660ec2 522 * GapAdvertisingData::Flags for valid flags. Multiple
rgrover1 710:b2e1a2660ec2 523 * flags may be specified in combination.
rgrover1 710:b2e1a2660ec2 524 */
rgrover1 710:b2e1a2660ec2 525 ble_error_t accumulateAdvertisingPayload(uint8_t flags) {
rgrover1 710:b2e1a2660ec2 526 ble_error_t rc;
rgrover1 710:b2e1a2660ec2 527 if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) {
rgrover1 710:b2e1a2660ec2 528 return rc;
rgrover1 710:b2e1a2660ec2 529 }
rgrover1 710:b2e1a2660ec2 530
rgrover1 710:b2e1a2660ec2 531 return setAdvertisingData();
rgrover1 710:b2e1a2660ec2 532 }
rgrover1 710:b2e1a2660ec2 533
rgrover1 710:b2e1a2660ec2 534 /**
rgrover1 710:b2e1a2660ec2 535 * Accumulate an AD structure in the advertising payload. Please note that
rgrover1 710:b2e1a2660ec2 536 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
rgrover1 993:4d62b7967c11 537 * as an additional 31 bytes if the advertising payload is too
rgrover1 710:b2e1a2660ec2 538 * small.
rgrover1 710:b2e1a2660ec2 539 *
rgrover1 710:b2e1a2660ec2 540 * @param app
rgrover1 710:b2e1a2660ec2 541 * The appearance of the peripheral.
rgrover1 710:b2e1a2660ec2 542 */
rgrover1 710:b2e1a2660ec2 543 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) {
rgrover1 710:b2e1a2660ec2 544 setAppearance(app);
rgrover1 710:b2e1a2660ec2 545
rgrover1 710:b2e1a2660ec2 546 ble_error_t rc;
rgrover1 710:b2e1a2660ec2 547 if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) {
rgrover1 710:b2e1a2660ec2 548 return rc;
rgrover1 710:b2e1a2660ec2 549 }
rgrover1 710:b2e1a2660ec2 550
rgrover1 710:b2e1a2660ec2 551 return setAdvertisingData();
rgrover1 710:b2e1a2660ec2 552 }
rgrover1 710:b2e1a2660ec2 553
rgrover1 710:b2e1a2660ec2 554 /**
rgrover1 710:b2e1a2660ec2 555 * Accumulate an AD structure in the advertising payload. Please note that
rgrover1 710:b2e1a2660ec2 556 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
rgrover1 993:4d62b7967c11 557 * as an additional 31 bytes if the advertising payload is too
rgrover1 710:b2e1a2660ec2 558 * small.
rgrover1 710:b2e1a2660ec2 559 *
rgrover1 993:4d62b7967c11 560 * @param power
rgrover1 764:1e560f0d45e1 561 * The max transmit power to be used by the controller (in dBm).
rgrover1 710:b2e1a2660ec2 562 */
rgrover1 710:b2e1a2660ec2 563 ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) {
rgrover1 710:b2e1a2660ec2 564 ble_error_t rc;
rgrover1 710:b2e1a2660ec2 565 if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) {
rgrover1 710:b2e1a2660ec2 566 return rc;
rgrover1 710:b2e1a2660ec2 567 }
rgrover1 710:b2e1a2660ec2 568
rgrover1 710:b2e1a2660ec2 569 return setAdvertisingData();
rgrover1 710:b2e1a2660ec2 570 }
rgrover1 710:b2e1a2660ec2 571
rgrover1 710:b2e1a2660ec2 572 /**
rgrover1 710:b2e1a2660ec2 573 * Accumulate a variable length byte-stream as an AD structure in the
rgrover1 710:b2e1a2660ec2 574 * advertising payload. Please note that the payload is limited to 31 bytes.
rgrover1 710:b2e1a2660ec2 575 * The SCAN_RESPONSE message may be used as an additional 31 bytes if the
rgrover1 993:4d62b7967c11 576 * advertising payload is too small.
rgrover1 710:b2e1a2660ec2 577 *
rgrover1 993:4d62b7967c11 578 * @param type The type describing the variable length data.
rgrover1 993:4d62b7967c11 579 * @param data Data bytes.
rgrover1 993:4d62b7967c11 580 * @param len Length of data.
rgrover1 710:b2e1a2660ec2 581 */
rgrover1 710:b2e1a2660ec2 582 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
rgrover1 710:b2e1a2660ec2 583 if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
rgrover1 710:b2e1a2660ec2 584 setDeviceName(data);
rgrover1 710:b2e1a2660ec2 585 }
rgrover1 710:b2e1a2660ec2 586
rgrover1 710:b2e1a2660ec2 587 ble_error_t rc;
rgrover1 710:b2e1a2660ec2 588 if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) {
rgrover1 710:b2e1a2660ec2 589 return rc;
rgrover1 710:b2e1a2660ec2 590 }
rgrover1 710:b2e1a2660ec2 591
rgrover1 710:b2e1a2660ec2 592 return setAdvertisingData();
rgrover1 710:b2e1a2660ec2 593 }
rgrover1 710:b2e1a2660ec2 594
rgrover1 710:b2e1a2660ec2 595 /**
rgrover1 765:4cd91998cd48 596 * Update a particular ADV field in the advertising payload (based on
rgrover1 765:4cd91998cd48 597 * matching type and length). Note: the length of the new data must be the
rgrover1 765:4cd91998cd48 598 * same as the old one.
rgrover1 763:36c3e2b1f1ae 599 *
rgrover1 993:4d62b7967c11 600 * @param[in] type The ADV type field describing the variable length data.
rgrover1 993:4d62b7967c11 601 * @param[in] data Data bytes.
rgrover1 993:4d62b7967c11 602 * @param[in] len Length of data.
rgrover1 765:4cd91998cd48 603 *
rgrover1 765:4cd91998cd48 604 * @note: If advertisements are enabled, then the update will take effect immediately.
rgrover1 765:4cd91998cd48 605 *
rgrover1 765:4cd91998cd48 606 * @return BLE_ERROR_NONE if the advertisement payload was updated based on
rgrover1 993:4d62b7967c11 607 * a <type, len> match; otherwise, an appropriate error.
rgrover1 763:36c3e2b1f1ae 608 */
rgrover1 763:36c3e2b1f1ae 609 ble_error_t updateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
rgrover1 763:36c3e2b1f1ae 610 if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
rgrover1 763:36c3e2b1f1ae 611 setDeviceName(data);
rgrover1 763:36c3e2b1f1ae 612 }
rgrover1 763:36c3e2b1f1ae 613
rgrover1 763:36c3e2b1f1ae 614 ble_error_t rc;
rgrover1 763:36c3e2b1f1ae 615 if ((rc = _advPayload.updateData(type, data, len)) != BLE_ERROR_NONE) {
rgrover1 763:36c3e2b1f1ae 616 return rc;
rgrover1 763:36c3e2b1f1ae 617 }
rgrover1 763:36c3e2b1f1ae 618
rgrover1 763:36c3e2b1f1ae 619 return setAdvertisingData();
rgrover1 763:36c3e2b1f1ae 620 }
rgrover1 763:36c3e2b1f1ae 621
rgrover1 763:36c3e2b1f1ae 622 /**
rgrover1 993:4d62b7967c11 623 * Set up a particular, user-constructed advertisement payload for the
rgrover1 710:b2e1a2660ec2 624 * underlying stack. It would be uncommon for this API to be used directly;
rgrover1 710:b2e1a2660ec2 625 * there are other APIs to build an advertisement payload (see above).
rgrover1 710:b2e1a2660ec2 626 */
rgrover1 710:b2e1a2660ec2 627 ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) {
rgrover1 710:b2e1a2660ec2 628 _advPayload = payload;
rgrover1 710:b2e1a2660ec2 629 return setAdvertisingData();
rgrover1 710:b2e1a2660ec2 630 }
rgrover1 710:b2e1a2660ec2 631
rgrover1 710:b2e1a2660ec2 632 /**
rgrover1 710:b2e1a2660ec2 633 * @return Read back advertising data. Useful for storing and
rgrover1 710:b2e1a2660ec2 634 * restoring payload.
rgrover1 710:b2e1a2660ec2 635 */
rgrover1 710:b2e1a2660ec2 636 const GapAdvertisingData &getAdvertisingPayload(void) const {
rgrover1 710:b2e1a2660ec2 637 return _advPayload;
rgrover1 710:b2e1a2660ec2 638 }
rgrover1 710:b2e1a2660ec2 639
rgrover1 710:b2e1a2660ec2 640 /**
rgrover1 710:b2e1a2660ec2 641 * Accumulate a variable length byte-stream as an AD structure in the
rgrover1 710:b2e1a2660ec2 642 * scanResponse payload.
rgrover1 710:b2e1a2660ec2 643 *
rgrover1 993:4d62b7967c11 644 * @param[in] type The type describing the variable length data.
rgrover1 993:4d62b7967c11 645 * @param[in] data Data bytes.
rgrover1 993:4d62b7967c11 646 * @param[in] len Length of data.
rgrover1 710:b2e1a2660ec2 647 */
rgrover1 710:b2e1a2660ec2 648 ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
rgrover1 710:b2e1a2660ec2 649 ble_error_t rc;
rgrover1 710:b2e1a2660ec2 650 if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) {
rgrover1 710:b2e1a2660ec2 651 return rc;
rgrover1 710:b2e1a2660ec2 652 }
rgrover1 710:b2e1a2660ec2 653
rgrover1 710:b2e1a2660ec2 654 return setAdvertisingData();
rgrover1 710:b2e1a2660ec2 655 }
rgrover1 710:b2e1a2660ec2 656
rgrover1 710:b2e1a2660ec2 657 /**
rgrover1 710:b2e1a2660ec2 658 * Reset any scan response prepared from prior calls to
rgrover1 710:b2e1a2660ec2 659 * accumulateScanResponse().
rgrover1 710:b2e1a2660ec2 660 *
rgrover1 710:b2e1a2660ec2 661 * Note: This should be followed by a call to setAdvertisingPayload() or
rgrover1 710:b2e1a2660ec2 662 * startAdvertising() before the update takes effect.
rgrover1 710:b2e1a2660ec2 663 */
rgrover1 710:b2e1a2660ec2 664 void clearScanResponse(void) {
rgrover1 710:b2e1a2660ec2 665 _scanResponse.clear();
rgrover1 710:b2e1a2660ec2 666 setAdvertisingData();
rgrover1 710:b2e1a2660ec2 667 }
rgrover1 710:b2e1a2660ec2 668
rgrover1 710:b2e1a2660ec2 669 /**
rgrover1 993:4d62b7967c11 670 * Set up parameters for GAP scanning (observer mode).
rgrover1 710:b2e1a2660ec2 671 * @param[in] interval
rgrover1 710:b2e1a2660ec2 672 * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
rgrover1 710:b2e1a2660ec2 673 * @param[in] window
rgrover1 710:b2e1a2660ec2 674 * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
rgrover1 710:b2e1a2660ec2 675 * @param[in] timeout
rgrover1 993:4d62b7967c11 676 * Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables the timeout.
rgrover1 710:b2e1a2660ec2 677 * @param[in] activeScanning
rgrover1 710:b2e1a2660ec2 678 * Set to True if active-scanning is required. This is used to fetch the
rgrover1 710:b2e1a2660ec2 679 * scan response from a peer if possible.
rgrover1 710:b2e1a2660ec2 680 *
rgrover1 710:b2e1a2660ec2 681 * The scanning window divided by the interval determines the duty cycle for
rgrover1 710:b2e1a2660ec2 682 * scanning. For example, if the interval is 100ms and the window is 10ms,
rgrover1 710:b2e1a2660ec2 683 * then the controller will scan for 10 percent of the time. It is possible
rgrover1 710:b2e1a2660ec2 684 * to have the interval and window set to the same value. In this case,
rgrover1 710:b2e1a2660ec2 685 * scanning is continuous, with a change of scanning frequency once every
rgrover1 710:b2e1a2660ec2 686 * interval.
rgrover1 710:b2e1a2660ec2 687 *
rgrover1 710:b2e1a2660ec2 688 * Once the scanning parameters have been configured, scanning can be
rgrover1 710:b2e1a2660ec2 689 * enabled by using startScan().
rgrover1 710:b2e1a2660ec2 690 *
rgrover1 710:b2e1a2660ec2 691 * @Note: The scan interval and window are recommendations to the BLE stack.
rgrover1 710:b2e1a2660ec2 692 */
rgrover1 710:b2e1a2660ec2 693 ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX,
rgrover1 710:b2e1a2660ec2 694 uint16_t window = GapScanningParams::SCAN_WINDOW_MAX,
rgrover1 710:b2e1a2660ec2 695 uint16_t timeout = 0,
rgrover1 710:b2e1a2660ec2 696 bool activeScanning = false) {
rgrover1 710:b2e1a2660ec2 697 ble_error_t rc;
rgrover1 710:b2e1a2660ec2 698 if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) &&
rgrover1 710:b2e1a2660ec2 699 ((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) &&
rgrover1 710:b2e1a2660ec2 700 ((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) {
rgrover1 710:b2e1a2660ec2 701 _scanningParams.setActiveScanning(activeScanning);
rgrover1 710:b2e1a2660ec2 702 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 703 }
rgrover1 710:b2e1a2660ec2 704
rgrover1 710:b2e1a2660ec2 705 return rc;
rgrover1 710:b2e1a2660ec2 706 }
rgrover1 710:b2e1a2660ec2 707
rgrover1 710:b2e1a2660ec2 708 /**
rgrover1 993:4d62b7967c11 709 * Set up the scanInterval parameter for GAP scanning (observer mode).
rgrover1 710:b2e1a2660ec2 710 * @param[in] interval
rgrover1 710:b2e1a2660ec2 711 * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
rgrover1 710:b2e1a2660ec2 712 *
rgrover1 710:b2e1a2660ec2 713 * The scanning window divided by the interval determines the duty cycle for
rgrover1 710:b2e1a2660ec2 714 * scanning. For example, if the interval is 100ms and the window is 10ms,
rgrover1 710:b2e1a2660ec2 715 * then the controller will scan for 10 percent of the time. It is possible
rgrover1 710:b2e1a2660ec2 716 * to have the interval and window set to the same value. In this case,
rgrover1 710:b2e1a2660ec2 717 * scanning is continuous, with a change of scanning frequency once every
rgrover1 710:b2e1a2660ec2 718 * interval.
rgrover1 710:b2e1a2660ec2 719 *
rgrover1 710:b2e1a2660ec2 720 * Once the scanning parameters have been configured, scanning can be
rgrover1 710:b2e1a2660ec2 721 * enabled by using startScan().
rgrover1 710:b2e1a2660ec2 722 */
rgrover1 710:b2e1a2660ec2 723 ble_error_t setScanInterval(uint16_t interval) {
rgrover1 710:b2e1a2660ec2 724 return _scanningParams.setInterval(interval);
rgrover1 710:b2e1a2660ec2 725 }
rgrover1 710:b2e1a2660ec2 726
rgrover1 710:b2e1a2660ec2 727 /**
rgrover1 993:4d62b7967c11 728 * Set up the scanWindow parameter for GAP scanning (observer mode).
rgrover1 710:b2e1a2660ec2 729 * @param[in] window
rgrover1 710:b2e1a2660ec2 730 * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
rgrover1 710:b2e1a2660ec2 731 *
rgrover1 710:b2e1a2660ec2 732 * The scanning window divided by the interval determines the duty cycle for
rgrover1 710:b2e1a2660ec2 733 * scanning. For example, if the interval is 100ms and the window is 10ms,
rgrover1 710:b2e1a2660ec2 734 * then the controller will scan for 10 percent of the time. It is possible
rgrover1 710:b2e1a2660ec2 735 * to have the interval and window set to the same value. In this case,
rgrover1 710:b2e1a2660ec2 736 * scanning is continuous, with a change of scanning frequency once every
rgrover1 710:b2e1a2660ec2 737 * interval.
rgrover1 710:b2e1a2660ec2 738 *
rgrover1 710:b2e1a2660ec2 739 * Once the scanning parameters have been configured, scanning can be
rgrover1 710:b2e1a2660ec2 740 * enabled by using startScan().
rgrover1 770:079b714e9c1a 741 *
rgrover1 770:079b714e9c1a 742 * If scanning is already active, the updated value of scanWindow will be
rgrover1 770:079b714e9c1a 743 * propagated to the underlying BLE stack.
rgrover1 710:b2e1a2660ec2 744 */
rgrover1 710:b2e1a2660ec2 745 ble_error_t setScanWindow(uint16_t window) {
rgrover1 770:079b714e9c1a 746 ble_error_t rc;
rgrover1 770:079b714e9c1a 747 if ((rc = _scanningParams.setWindow(window)) != BLE_ERROR_NONE) {
rgrover1 770:079b714e9c1a 748 return rc;
rgrover1 770:079b714e9c1a 749 }
rgrover1 770:079b714e9c1a 750
rgrover1 770:079b714e9c1a 751 /* If scanning is already active, propagate the new setting to the stack. */
rgrover1 770:079b714e9c1a 752 if (scanningActive) {
rgrover1 770:079b714e9c1a 753 return startRadioScan(_scanningParams);
rgrover1 770:079b714e9c1a 754 }
rgrover1 770:079b714e9c1a 755
rgrover1 770:079b714e9c1a 756 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 757 }
rgrover1 710:b2e1a2660ec2 758
rgrover1 710:b2e1a2660ec2 759 /**
rgrover1 993:4d62b7967c11 760 * Set up parameters for GAP scanning (observer mode).
rgrover1 710:b2e1a2660ec2 761 * @param[in] timeout
rgrover1 993:4d62b7967c11 762 * Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables the timeout.
rgrover1 710:b2e1a2660ec2 763 *
rgrover1 710:b2e1a2660ec2 764 * Once the scanning parameters have been configured, scanning can be
rgrover1 710:b2e1a2660ec2 765 * enabled by using startScan().
rgrover1 770:079b714e9c1a 766 *
rgrover1 770:079b714e9c1a 767 * If scanning is already active, the updated value of scanTimeout will be
rgrover1 770:079b714e9c1a 768 * propagated to the underlying BLE stack.
rgrover1 710:b2e1a2660ec2 769 */
rgrover1 710:b2e1a2660ec2 770 ble_error_t setScanTimeout(uint16_t timeout) {
rgrover1 770:079b714e9c1a 771 ble_error_t rc;
rgrover1 770:079b714e9c1a 772 if ((rc = _scanningParams.setTimeout(timeout)) != BLE_ERROR_NONE) {
rgrover1 770:079b714e9c1a 773 return rc;
rgrover1 770:079b714e9c1a 774 }
rgrover1 770:079b714e9c1a 775
rgrover1 770:079b714e9c1a 776 /* If scanning is already active, propagate the new settings to the stack. */
rgrover1 770:079b714e9c1a 777 if (scanningActive) {
rgrover1 770:079b714e9c1a 778 return startRadioScan(_scanningParams);
rgrover1 770:079b714e9c1a 779 }
rgrover1 770:079b714e9c1a 780
rgrover1 770:079b714e9c1a 781 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 782 }
rgrover1 710:b2e1a2660ec2 783
rgrover1 710:b2e1a2660ec2 784 /**
rgrover1 993:4d62b7967c11 785 * Set up parameters for GAP scanning (observer mode).
rgrover1 710:b2e1a2660ec2 786 * @param[in] activeScanning
rgrover1 710:b2e1a2660ec2 787 * Set to True if active-scanning is required. This is used to fetch the
rgrover1 710:b2e1a2660ec2 788 * scan response from a peer if possible.
rgrover1 710:b2e1a2660ec2 789 *
rgrover1 710:b2e1a2660ec2 790 * Once the scanning parameters have been configured, scanning can be
rgrover1 710:b2e1a2660ec2 791 * enabled by using startScan().
rgrover1 770:079b714e9c1a 792 *
rgrover1 770:079b714e9c1a 793 * If scanning is already in progress, then active-scanning will be enabled
rgrover1 770:079b714e9c1a 794 * for the underlying BLE stack.
rgrover1 710:b2e1a2660ec2 795 */
rgrover1 770:079b714e9c1a 796 ble_error_t setActiveScanning(bool activeScanning) {
rgrover1 710:b2e1a2660ec2 797 _scanningParams.setActiveScanning(activeScanning);
rgrover1 770:079b714e9c1a 798
rgrover1 770:079b714e9c1a 799 /* If scanning is already active, propagate the new settings to the stack. */
rgrover1 770:079b714e9c1a 800 if (scanningActive) {
rgrover1 770:079b714e9c1a 801 return startRadioScan(_scanningParams);
rgrover1 770:079b714e9c1a 802 }
rgrover1 770:079b714e9c1a 803
rgrover1 770:079b714e9c1a 804 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 805 }
rgrover1 710:b2e1a2660ec2 806
rgrover1 710:b2e1a2660ec2 807 /**
rgrover1 710:b2e1a2660ec2 808 * Start scanning (Observer Procedure) based on the parameters currently in
rgrover1 710:b2e1a2660ec2 809 * effect.
rgrover1 710:b2e1a2660ec2 810 *
rgrover1 710:b2e1a2660ec2 811 * @param[in] callback
rgrover1 993:4d62b7967c11 812 * The application-specific callback to be invoked upon
rgrover1 710:b2e1a2660ec2 813 * receiving every advertisement report. This can be passed in
rgrover1 710:b2e1a2660ec2 814 * as NULL, in which case scanning may not be enabled at all.
rgrover1 710:b2e1a2660ec2 815 */
rgrover1 710:b2e1a2660ec2 816 ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) {
rgrover1 710:b2e1a2660ec2 817 ble_error_t err = BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 818 if (callback) {
rgrover1 710:b2e1a2660ec2 819 if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
rgrover1 770:079b714e9c1a 820 scanningActive = true;
rgrover1 710:b2e1a2660ec2 821 onAdvertisementReport.attach(callback);
rgrover1 710:b2e1a2660ec2 822 }
rgrover1 710:b2e1a2660ec2 823 }
rgrover1 710:b2e1a2660ec2 824
rgrover1 710:b2e1a2660ec2 825 return err;
rgrover1 710:b2e1a2660ec2 826 }
rgrover1 710:b2e1a2660ec2 827
rgrover1 710:b2e1a2660ec2 828 /**
rgrover1 710:b2e1a2660ec2 829 * Same as above, but this takes an (object, method) pair for a callback.
rgrover1 710:b2e1a2660ec2 830 */
rgrover1 710:b2e1a2660ec2 831 template<typename T>
rgrover1 710:b2e1a2660ec2 832 ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) {
rgrover1 710:b2e1a2660ec2 833 ble_error_t err = BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 834 if (object && callbackMember) {
rgrover1 710:b2e1a2660ec2 835 if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
rgrover1 770:079b714e9c1a 836 scanningActive = true;
rgrover1 710:b2e1a2660ec2 837 onAdvertisementReport.attach(object, callbackMember);
rgrover1 710:b2e1a2660ec2 838 }
rgrover1 710:b2e1a2660ec2 839 }
rgrover1 710:b2e1a2660ec2 840
rgrover1 710:b2e1a2660ec2 841 return err;
rgrover1 710:b2e1a2660ec2 842 }
rgrover1 710:b2e1a2660ec2 843
rgrover1 753:0f60274cd3ad 844 /**
rgrover1 753:0f60274cd3ad 845 * Initialize radio-notification events to be generated from the stack.
rgrover1 993:4d62b7967c11 846 * This API doesn't need to be called directly.
rgrover1 753:0f60274cd3ad 847 *
rgrover1 753:0f60274cd3ad 848 * Radio Notification is a feature that enables ACTIVE and INACTIVE
rgrover1 753:0f60274cd3ad 849 * (nACTIVE) signals from the stack that notify the application when the
rgrover1 753:0f60274cd3ad 850 * radio is in use.
rgrover1 753:0f60274cd3ad 851 *
rgrover1 993:4d62b7967c11 852 * The ACTIVE signal is sent before the radio event starts. The nACTIVE
rgrover1 993:4d62b7967c11 853 * signal is sent at the end of the radio event. These signals can be used
rgrover1 753:0f60274cd3ad 854 * by the application programmer to synchronize application logic with radio
rgrover1 753:0f60274cd3ad 855 * activity. For example, the ACTIVE signal can be used to shut off external
rgrover1 993:4d62b7967c11 856 * devices, to manage peak current drawn during periods when the radio is on,
rgrover1 753:0f60274cd3ad 857 * or to trigger sensor data collection for transmission in the Radio Event.
rgrover1 753:0f60274cd3ad 858 *
rgrover1 753:0f60274cd3ad 859 * @return BLE_ERROR_NONE on successful initialization, otherwise an error code.
rgrover1 753:0f60274cd3ad 860 */
rgrover1 753:0f60274cd3ad 861 virtual ble_error_t initRadioNotification(void) {
rgrover1 753:0f60274cd3ad 862 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
rgrover1 753:0f60274cd3ad 863 }
rgrover1 753:0f60274cd3ad 864
rgrover1 710:b2e1a2660ec2 865 private:
rgrover1 710:b2e1a2660ec2 866 ble_error_t setAdvertisingData(void) {
rgrover1 710:b2e1a2660ec2 867 return setAdvertisingData(_advPayload, _scanResponse);
rgrover1 710:b2e1a2660ec2 868 }
rgrover1 710:b2e1a2660ec2 869
rgrover1 710:b2e1a2660ec2 870 private:
rgrover1 896:791741895cd8 871 virtual ble_error_t setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) = 0;
rgrover1 896:791741895cd8 872 virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0;
rgrover1 710:b2e1a2660ec2 873
rgrover1 710:b2e1a2660ec2 874 public:
rgrover1 710:b2e1a2660ec2 875 /**
rgrover1 710:b2e1a2660ec2 876 * Accessors to read back currently active advertising params.
rgrover1 710:b2e1a2660ec2 877 */
rgrover1 710:b2e1a2660ec2 878 GapAdvertisingParams &getAdvertisingParams(void) {
rgrover1 710:b2e1a2660ec2 879 return _advParams;
rgrover1 710:b2e1a2660ec2 880 }
rgrover1 710:b2e1a2660ec2 881 const GapAdvertisingParams &getAdvertisingParams(void) const {
rgrover1 710:b2e1a2660ec2 882 return _advParams;
rgrover1 710:b2e1a2660ec2 883 }
rgrover1 710:b2e1a2660ec2 884
rgrover1 710:b2e1a2660ec2 885 /**
rgrover1 993:4d62b7967c11 886 * Set up a particular, user-constructed set of advertisement parameters for
rgrover1 710:b2e1a2660ec2 887 * the underlying stack. It would be uncommon for this API to be used
rgrover1 710:b2e1a2660ec2 888 * directly; there are other APIs to tweak advertisement parameters
rgrover1 710:b2e1a2660ec2 889 * individually.
rgrover1 710:b2e1a2660ec2 890 */
rgrover1 710:b2e1a2660ec2 891 void setAdvertisingParams(const GapAdvertisingParams &newParams) {
rgrover1 710:b2e1a2660ec2 892 _advParams = newParams;
rgrover1 710:b2e1a2660ec2 893 }
rgrover1 710:b2e1a2660ec2 894
rgrover1 710:b2e1a2660ec2 895 /* Event callback handlers. */
rgrover1 710:b2e1a2660ec2 896 public:
rgrover1 710:b2e1a2660ec2 897 /**
rgrover1 993:4d62b7967c11 898 * Set up a callback for timeout events. Refer to TimeoutSource_t for
rgrover1 710:b2e1a2660ec2 899 * possible event types.
rgrover1 993:4d62b7967c11 900 * @note It is possible to unregister callbacks using onTimeout().detach(callback)
rgrover1 710:b2e1a2660ec2 901 */
rgrover1 993:4d62b7967c11 902 void onTimeout(TimeoutEventCallback_t callback) {
rgrover1 993:4d62b7967c11 903 timeoutCallbackChain.add(callback);
rgrover1 993:4d62b7967c11 904 }
rgrover1 993:4d62b7967c11 905
rgrover1 993:4d62b7967c11 906 /**
rgrover1 993:4d62b7967c11 907 * @brief provide access to the callchain of timeout event callbacks
rgrover1 993:4d62b7967c11 908 * It is possible to register callbacks using onTimeout().add(callback);
rgrover1 1017:ccb8c0646e55 909 * It is possible to unregister callbacks using onTimeout().detach(callback)
rgrover1 993:4d62b7967c11 910 * @return The timeout event callbacks chain
rgrover1 993:4d62b7967c11 911 */
rgrover1 993:4d62b7967c11 912 TimeoutEventCallbackChain_t& onTimeout() {
rgrover1 993:4d62b7967c11 913 return timeoutCallbackChain;
rgrover1 993:4d62b7967c11 914 }
rgrover1 710:b2e1a2660ec2 915
rgrover1 710:b2e1a2660ec2 916 /**
rgrover1 829:9072de50087b 917 * Append to a chain of callbacks to be invoked upon GAP connection.
rgrover1 993:4d62b7967c11 918 * @note It is possible to unregister callbacks using onConnection().detach(callback)
rgrover1 710:b2e1a2660ec2 919 */
rgrover1 829:9072de50087b 920 void onConnection(ConnectionEventCallback_t callback) {connectionCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 921
rgrover1 829:9072de50087b 922 template<typename T>
rgrover1 829:9072de50087b 923 void onConnection(T *tptr, void (T::*mptr)(const ConnectionCallbackParams_t*)) {connectionCallChain.add(tptr, mptr);}
rgrover1 710:b2e1a2660ec2 924
rgrover1 710:b2e1a2660ec2 925 /**
rgrover1 993:4d62b7967c11 926 * @brief provide access to the callchain of connection event callbacks
rgrover1 993:4d62b7967c11 927 * It is possible to register callbacks using onConnection().add(callback);
rgrover1 1017:ccb8c0646e55 928 * It is possible to unregister callbacks using onConnection().detach(callback)
rgrover1 993:4d62b7967c11 929 * @return The connection event callbacks chain
rgrover1 993:4d62b7967c11 930 */
rgrover1 1017:ccb8c0646e55 931 ConnectionEventCallbackChain_t& onconnection() {
rgrover1 993:4d62b7967c11 932 return connectionCallChain;
rgrover1 993:4d62b7967c11 933 }
rgrover1 993:4d62b7967c11 934
rgrover1 993:4d62b7967c11 935 /**
rgrover1 829:9072de50087b 936 * Append to a chain of callbacks to be invoked upon GAP disconnection.
rgrover1 993:4d62b7967c11 937 * @note It is possible to unregister callbacks using onDisconnection().detach(callback)
rgrover1 816:2b4f0ef8c06e 938 */
rgrover1 829:9072de50087b 939 void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallChain.add(callback);}
rgrover1 816:2b4f0ef8c06e 940
rgrover1 710:b2e1a2660ec2 941 template<typename T>
rgrover1 829:9072de50087b 942 void onDisconnection(T *tptr, void (T::*mptr)(const DisconnectionCallbackParams_t*)) {disconnectionCallChain.add(tptr, mptr);}
rgrover1 710:b2e1a2660ec2 943
rgrover1 710:b2e1a2660ec2 944 /**
rgrover1 993:4d62b7967c11 945 * @brief provide access to the callchain of disconnection event callbacks
rgrover1 993:4d62b7967c11 946 * It is possible to register callbacks using onDisconnection().add(callback);
rgrover1 1017:ccb8c0646e55 947 * It is possible to unregister callbacks using onDisconnection().detach(callback)
rgrover1 993:4d62b7967c11 948 * @return The disconnection event callbacks chain
rgrover1 993:4d62b7967c11 949 */
rgrover1 993:4d62b7967c11 950 DisconnectionEventCallbackChain_t& onDisconnection() {
rgrover1 993:4d62b7967c11 951 return disconnectionCallChain;
rgrover1 993:4d62b7967c11 952 }
rgrover1 993:4d62b7967c11 953
rgrover1 993:4d62b7967c11 954 /**
rgrover1 710:b2e1a2660ec2 955 * Set the application callback for radio-notification events.
rgrover1 710:b2e1a2660ec2 956 *
rgrover1 710:b2e1a2660ec2 957 * Radio Notification is a feature that enables ACTIVE and INACTIVE
rgrover1 710:b2e1a2660ec2 958 * (nACTIVE) signals from the stack that notify the application when the
rgrover1 753:0f60274cd3ad 959 * radio is in use.
rgrover1 710:b2e1a2660ec2 960 *
rgrover1 993:4d62b7967c11 961 * The ACTIVE signal is sent before the radio event starts. The nACTIVE
rgrover1 993:4d62b7967c11 962 * signal is sent at the end of the radio event. These signals can be used
rgrover1 710:b2e1a2660ec2 963 * by the application programmer to synchronize application logic with radio
rgrover1 710:b2e1a2660ec2 964 * activity. For example, the ACTIVE signal can be used to shut off external
rgrover1 993:4d62b7967c11 965 * devices, to manage peak current drawn during periods when the radio is on,
rgrover1 710:b2e1a2660ec2 966 * or to trigger sensor data collection for transmission in the Radio Event.
rgrover1 710:b2e1a2660ec2 967 *
rgrover1 710:b2e1a2660ec2 968 * @param callback
rgrover1 710:b2e1a2660ec2 969 * The application handler to be invoked in response to a radio
rgrover1 710:b2e1a2660ec2 970 * ACTIVE/INACTIVE event.
rgrover1 754:9b391fb5c5d7 971 *
rgrover1 993:4d62b7967c11 972 * Or in the other version:
rgrover1 754:9b391fb5c5d7 973 *
rgrover1 754:9b391fb5c5d7 974 * @param tptr
rgrover1 754:9b391fb5c5d7 975 * Pointer to the object of a class defining the member callback
rgrover1 754:9b391fb5c5d7 976 * function (mptr).
rgrover1 754:9b391fb5c5d7 977 * @param mptr
rgrover1 754:9b391fb5c5d7 978 * The member callback (within the context of an object) to be
rgrover1 754:9b391fb5c5d7 979 * invoked in response to a radio ACTIVE/INACTIVE event.
rgrover1 710:b2e1a2660ec2 980 */
rgrover1 753:0f60274cd3ad 981 void onRadioNotification(void (*callback)(bool param)) {
rgrover1 753:0f60274cd3ad 982 radioNotificationCallback.attach(callback);
rgrover1 753:0f60274cd3ad 983 }
rgrover1 753:0f60274cd3ad 984 template <typename T>
rgrover1 753:0f60274cd3ad 985 void onRadioNotification(T *tptr, void (T::*mptr)(bool)) {
rgrover1 753:0f60274cd3ad 986 radioNotificationCallback.attach(tptr, mptr);
rgrover1 753:0f60274cd3ad 987 }
rgrover1 710:b2e1a2660ec2 988
rgrover1 710:b2e1a2660ec2 989 protected:
rgrover1 710:b2e1a2660ec2 990 Gap() :
rgrover1 710:b2e1a2660ec2 991 _advParams(),
rgrover1 710:b2e1a2660ec2 992 _advPayload(),
rgrover1 710:b2e1a2660ec2 993 _scanningParams(),
rgrover1 710:b2e1a2660ec2 994 _scanResponse(),
rgrover1 710:b2e1a2660ec2 995 state(),
rgrover1 770:079b714e9c1a 996 scanningActive(false),
rgrover1 993:4d62b7967c11 997 timeoutCallbackChain(),
rgrover1 710:b2e1a2660ec2 998 radioNotificationCallback(),
rgrover1 710:b2e1a2660ec2 999 onAdvertisementReport(),
rgrover1 816:2b4f0ef8c06e 1000 connectionCallChain(),
rgrover1 710:b2e1a2660ec2 1001 disconnectionCallChain() {
rgrover1 710:b2e1a2660ec2 1002 _advPayload.clear();
rgrover1 710:b2e1a2660ec2 1003 _scanResponse.clear();
rgrover1 710:b2e1a2660ec2 1004 }
rgrover1 710:b2e1a2660ec2 1005
rgrover1 710:b2e1a2660ec2 1006 /* Entry points for the underlying stack to report events back to the user. */
rgrover1 710:b2e1a2660ec2 1007 public:
rgrover1 710:b2e1a2660ec2 1008 void processConnectionEvent(Handle_t handle,
rgrover1 710:b2e1a2660ec2 1009 Role_t role,
rgrover1 710:b2e1a2660ec2 1010 AddressType_t peerAddrType,
rgrover1 710:b2e1a2660ec2 1011 const Address_t peerAddr,
rgrover1 710:b2e1a2660ec2 1012 AddressType_t ownAddrType,
rgrover1 710:b2e1a2660ec2 1013 const Address_t ownAddr,
rgrover1 710:b2e1a2660ec2 1014 const ConnectionParams_t *connectionParams) {
rgrover1 710:b2e1a2660ec2 1015 state.connected = 1;
rgrover1 829:9072de50087b 1016 ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams);
rgrover1 829:9072de50087b 1017 connectionCallChain.call(&callbackParams);
rgrover1 710:b2e1a2660ec2 1018 }
rgrover1 710:b2e1a2660ec2 1019
rgrover1 710:b2e1a2660ec2 1020 void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) {
rgrover1 710:b2e1a2660ec2 1021 state.connected = 0;
rgrover1 829:9072de50087b 1022 DisconnectionCallbackParams_t callbackParams(handle, reason);
rgrover1 829:9072de50087b 1023 disconnectionCallChain.call(&callbackParams);
rgrover1 710:b2e1a2660ec2 1024 }
rgrover1 710:b2e1a2660ec2 1025
rgrover1 710:b2e1a2660ec2 1026 void processAdvertisementReport(const Address_t peerAddr,
rgrover1 710:b2e1a2660ec2 1027 int8_t rssi,
rgrover1 710:b2e1a2660ec2 1028 bool isScanResponse,
rgrover1 710:b2e1a2660ec2 1029 GapAdvertisingParams::AdvertisingType_t type,
rgrover1 710:b2e1a2660ec2 1030 uint8_t advertisingDataLen,
rgrover1 710:b2e1a2660ec2 1031 const uint8_t *advertisingData) {
rgrover1 710:b2e1a2660ec2 1032 AdvertisementCallbackParams_t params;
rgrover1 710:b2e1a2660ec2 1033 memcpy(params.peerAddr, peerAddr, ADDR_LEN);
rgrover1 710:b2e1a2660ec2 1034 params.rssi = rssi;
rgrover1 710:b2e1a2660ec2 1035 params.isScanResponse = isScanResponse;
rgrover1 710:b2e1a2660ec2 1036 params.type = type;
rgrover1 710:b2e1a2660ec2 1037 params.advertisingDataLen = advertisingDataLen;
rgrover1 710:b2e1a2660ec2 1038 params.advertisingData = advertisingData;
rgrover1 710:b2e1a2660ec2 1039 onAdvertisementReport.call(&params);
rgrover1 710:b2e1a2660ec2 1040 }
rgrover1 710:b2e1a2660ec2 1041
rgrover1 710:b2e1a2660ec2 1042 void processTimeoutEvent(TimeoutSource_t source) {
rgrover1 993:4d62b7967c11 1043 if (timeoutCallbackChain) {
rgrover1 993:4d62b7967c11 1044 timeoutCallbackChain(source);
rgrover1 710:b2e1a2660ec2 1045 }
rgrover1 710:b2e1a2660ec2 1046 }
rgrover1 710:b2e1a2660ec2 1047
rgrover1 710:b2e1a2660ec2 1048 protected:
rgrover1 710:b2e1a2660ec2 1049 GapAdvertisingParams _advParams;
rgrover1 710:b2e1a2660ec2 1050 GapAdvertisingData _advPayload;
rgrover1 710:b2e1a2660ec2 1051 GapScanningParams _scanningParams;
rgrover1 710:b2e1a2660ec2 1052 GapAdvertisingData _scanResponse;
rgrover1 710:b2e1a2660ec2 1053
rgrover1 710:b2e1a2660ec2 1054 GapState_t state;
rgrover1 770:079b714e9c1a 1055 bool scanningActive;
rgrover1 710:b2e1a2660ec2 1056
rgrover1 710:b2e1a2660ec2 1057 protected:
rgrover1 993:4d62b7967c11 1058 TimeoutEventCallbackChain_t timeoutCallbackChain;
rgrover1 993:4d62b7967c11 1059 RadioNotificationEventCallback_t radioNotificationCallback;
rgrover1 993:4d62b7967c11 1060 AdvertisementReportCallback_t onAdvertisementReport;
rgrover1 993:4d62b7967c11 1061 ConnectionEventCallbackChain_t connectionCallChain;
rgrover1 993:4d62b7967c11 1062 DisconnectionEventCallbackChain_t disconnectionCallChain;
rgrover1 710:b2e1a2660ec2 1063
rgrover1 710:b2e1a2660ec2 1064 private:
rgrover1 993:4d62b7967c11 1065 /* Disallow copy and assignment. */
rgrover1 710:b2e1a2660ec2 1066 Gap(const Gap &);
rgrover1 710:b2e1a2660ec2 1067 Gap& operator=(const Gap &);
rgrover1 710:b2e1a2660ec2 1068 };
rgrover1 710:b2e1a2660ec2 1069
rgrover1 710:b2e1a2660ec2 1070 #endif // ifndef __GAP_H__