High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Mon Jan 11 08:51:49 2016 +0000
Revision:
1088:709ebced28ab
Parent:
1087:4c6e11878033
Child:
1089:8e810a8e083e
Synchronized with git rev 0781293b
Author: Andres Amaya Garcia
Add onShutdown to register callbacks

Add an onShutdown() function to Gap, GattClient, GattServer and
SecurityManager. The callbacks are added to a private callback chain in each of
the instances. The callbacks will be executed inside each object's reset()
function BEFORE the state of the instance is cleared. The developers of the
platform-specific implementation must call the parent class' reset() function
for the callbacks to be executed.

Finally, an onShutdown() function that returns the shutdown callchain is added
to allow detaching callbacks.

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