Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_API by
public/Gap.h@537:00d5affbb2b2, 2015-06-19 (annotated)
- Committer:
- rgrover1
- Date:
- Fri Jun 19 15:52:08 2015 +0100
- Revision:
- 537:00d5affbb2b2
- Parent:
- 534:754131484cf1
- Child:
- 541:aa30f63e7b3f
Synchronized with git rev 68683f1c
Author: Rohit Grover
deprecate all GAP APIs from within BLE;
add consistent comment headers.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| rgrover1 | 260:ea7f9f14cc15 | 1 | /* mbed Microcontroller Library |
| rgrover1 | 260:ea7f9f14cc15 | 2 | * Copyright (c) 2006-2013 ARM Limited |
| rgrover1 | 260:ea7f9f14cc15 | 3 | * |
| rgrover1 | 260:ea7f9f14cc15 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| rgrover1 | 260:ea7f9f14cc15 | 5 | * you may not use this file except in compliance with the License. |
| rgrover1 | 260:ea7f9f14cc15 | 6 | * You may obtain a copy of the License at |
| rgrover1 | 260:ea7f9f14cc15 | 7 | * |
| rgrover1 | 260:ea7f9f14cc15 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| rgrover1 | 260:ea7f9f14cc15 | 9 | * |
| rgrover1 | 260:ea7f9f14cc15 | 10 | * Unless required by applicable law or agreed to in writing, software |
| rgrover1 | 260:ea7f9f14cc15 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| rgrover1 | 260:ea7f9f14cc15 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| rgrover1 | 260:ea7f9f14cc15 | 13 | * See the License for the specific language governing permissions and |
| rgrover1 | 260:ea7f9f14cc15 | 14 | * limitations under the License. |
| rgrover1 | 260:ea7f9f14cc15 | 15 | */ |
| rgrover1 | 260:ea7f9f14cc15 | 16 | |
| rgrover1 | 260:ea7f9f14cc15 | 17 | #ifndef __GAP_H__ |
| rgrover1 | 260:ea7f9f14cc15 | 18 | #define __GAP_H__ |
| rgrover1 | 260:ea7f9f14cc15 | 19 | |
| rgrover1 | 531:bdcd44b03974 | 20 | #include "GapAdvertisingData.h" |
| rgrover1 | 531:bdcd44b03974 | 21 | #include "GapAdvertisingParams.h" |
| rgrover1 | 531:bdcd44b03974 | 22 | #include "GapScanningParams.h" |
| rgrover1 | 260:ea7f9f14cc15 | 23 | #include "GapEvents.h" |
| rgrover1 | 260:ea7f9f14cc15 | 24 | #include "CallChain.h" |
| rgrover1 | 406:cec6778acc66 | 25 | #include "FunctionPointerWithContext.h" |
| rgrover1 | 260:ea7f9f14cc15 | 26 | |
| rgrover1 | 260:ea7f9f14cc15 | 27 | using namespace mbed; |
| rgrover1 | 260:ea7f9f14cc15 | 28 | |
| rgrover1 | 527:493185cebc03 | 29 | /* Forward declarations for classes which will only be used for pointers or references in the following. */ |
| rgrover1 | 527:493185cebc03 | 30 | class GapAdvertisingParams; |
| rgrover1 | 527:493185cebc03 | 31 | class GapScanningParams; |
| rgrover1 | 527:493185cebc03 | 32 | class GapAdvertisingData; |
| rgrover1 | 397:9f5bfae7ea50 | 33 | |
| rgrover1 | 260:ea7f9f14cc15 | 34 | class Gap { |
| rgrover1 | 260:ea7f9f14cc15 | 35 | public: |
| rgrover1 | 375:9cb0b006227e | 36 | enum AddressType_t { |
| rgrover1 | 260:ea7f9f14cc15 | 37 | ADDR_TYPE_PUBLIC = 0, |
| rgrover1 | 260:ea7f9f14cc15 | 38 | ADDR_TYPE_RANDOM_STATIC, |
| rgrover1 | 260:ea7f9f14cc15 | 39 | ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, |
| rgrover1 | 260:ea7f9f14cc15 | 40 | ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE |
| rgrover1 | 375:9cb0b006227e | 41 | }; |
| rgrover1 | 402:0e714ad205b4 | 42 | typedef enum AddressType_t addr_type_t; /* @Note: deprecated. Use AddressType_t instead. */ |
| rgrover1 | 260:ea7f9f14cc15 | 43 | |
| rgrover1 | 260:ea7f9f14cc15 | 44 | static const unsigned ADDR_LEN = 6; |
| rgrover1 | 375:9cb0b006227e | 45 | typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */ |
| rgrover1 | 402:0e714ad205b4 | 46 | typedef Address_t address_t; /* @Note: deprecated. Use Address_t instead. */ |
| rgrover1 | 260:ea7f9f14cc15 | 47 | |
| rgrover1 | 260:ea7f9f14cc15 | 48 | /** |
| rgrover1 | 260:ea7f9f14cc15 | 49 | * Enumeration for disconnection reasons. The values for these reasons are |
| rgrover1 | 260:ea7f9f14cc15 | 50 | * derived from Nordic's implementation; but the reasons are meant to be |
| rgrover1 | 260:ea7f9f14cc15 | 51 | * independent of the transport. If you are returned a reason which is not |
| rgrover1 | 260:ea7f9f14cc15 | 52 | * covered by this enumeration, then please refer to the underlying |
| rgrover1 | 260:ea7f9f14cc15 | 53 | * transport library. |
| rgrover1 | 260:ea7f9f14cc15 | 54 | */ |
| rgrover1 | 260:ea7f9f14cc15 | 55 | enum DisconnectionReason_t { |
| rgrover1 | 526:caa67c3187a0 | 56 | CONNECTION_TIMEOUT = 0x08, |
| rgrover1 | 526:caa67c3187a0 | 57 | REMOTE_USER_TERMINATED_CONNECTION = 0x13, |
| rgrover1 | 526:caa67c3187a0 | 58 | REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote Device Terminated Connection due to low resources.*/ |
| rgrover1 | 526:caa67c3187a0 | 59 | REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote Device Terminated Connection due to power off. */ |
| rgrover1 | 526:caa67c3187a0 | 60 | LOCAL_HOST_TERMINATED_CONNECTION = 0x16, |
| rgrover1 | 526:caa67c3187a0 | 61 | CONN_INTERVAL_UNACCEPTABLE = 0x3B, |
| rgrover1 | 260:ea7f9f14cc15 | 62 | }; |
| rgrover1 | 260:ea7f9f14cc15 | 63 | |
| rgrover1 | 260:ea7f9f14cc15 | 64 | /* Describes the current state of the device (more than one bit can be set) */ |
| rgrover1 | 413:4d5fb1522cfb | 65 | struct GapState_t { |
| rgrover1 | 260:ea7f9f14cc15 | 66 | unsigned advertising : 1; /**< peripheral is currently advertising */ |
| rgrover1 | 260:ea7f9f14cc15 | 67 | unsigned connected : 1; /**< peripheral is connected to a central */ |
| rgrover1 | 413:4d5fb1522cfb | 68 | }; |
| rgrover1 | 260:ea7f9f14cc15 | 69 | |
| rgrover1 | 260:ea7f9f14cc15 | 70 | typedef uint16_t Handle_t; |
| rgrover1 | 260:ea7f9f14cc15 | 71 | |
| rgrover1 | 260:ea7f9f14cc15 | 72 | typedef struct { |
| rgrover1 | 260:ea7f9f14cc15 | 73 | uint16_t minConnectionInterval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ |
| rgrover1 | 260:ea7f9f14cc15 | 74 | uint16_t maxConnectionInterval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ |
| rgrover1 | 260:ea7f9f14cc15 | 75 | uint16_t slaveLatency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ |
| rgrover1 | 260:ea7f9f14cc15 | 76 | uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ |
| rgrover1 | 260:ea7f9f14cc15 | 77 | } ConnectionParams_t; |
| rgrover1 | 260:ea7f9f14cc15 | 78 | |
| rgrover1 | 527:493185cebc03 | 79 | enum Role_t { |
| rgrover1 | 527:493185cebc03 | 80 | PERIPHERAL = 0x1, /**< Peripheral Role. */ |
| rgrover1 | 527:493185cebc03 | 81 | CENTRAL = 0x2, /**< Central Role. */ |
| rgrover1 | 527:493185cebc03 | 82 | }; |
| rgrover1 | 527:493185cebc03 | 83 | |
| rgrover1 | 527:493185cebc03 | 84 | struct AdvertisementCallbackParams_t { |
| rgrover1 | 527:493185cebc03 | 85 | Address_t peerAddr; |
| rgrover1 | 527:493185cebc03 | 86 | int8_t rssi; |
| rgrover1 | 527:493185cebc03 | 87 | bool isScanResponse; |
| rgrover1 | 537:00d5affbb2b2 | 88 | GapAdvertisingParams::AdvertisingType_t type; |
| rgrover1 | 527:493185cebc03 | 89 | uint8_t advertisingDataLen; |
| rgrover1 | 527:493185cebc03 | 90 | const uint8_t *advertisingData; |
| rgrover1 | 527:493185cebc03 | 91 | }; |
| rgrover1 | 527:493185cebc03 | 92 | typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; |
| rgrover1 | 527:493185cebc03 | 93 | |
| rgrover1 | 527:493185cebc03 | 94 | struct ConnectionCallbackParams_t { |
| rgrover1 | 527:493185cebc03 | 95 | Handle_t handle; |
| rgrover1 | 527:493185cebc03 | 96 | Role_t role; |
| rgrover1 | 527:493185cebc03 | 97 | AddressType_t peerAddrType; |
| rgrover1 | 527:493185cebc03 | 98 | Address_t peerAddr; |
| rgrover1 | 527:493185cebc03 | 99 | AddressType_t ownAddrType; |
| rgrover1 | 527:493185cebc03 | 100 | Address_t ownAddr; |
| rgrover1 | 527:493185cebc03 | 101 | const ConnectionParams_t *connectionParams; |
| rgrover1 | 527:493185cebc03 | 102 | |
| rgrover1 | 527:493185cebc03 | 103 | ConnectionCallbackParams_t(Handle_t handleIn, |
| rgrover1 | 527:493185cebc03 | 104 | Role_t roleIn, |
| rgrover1 | 527:493185cebc03 | 105 | AddressType_t peerAddrTypeIn, |
| rgrover1 | 527:493185cebc03 | 106 | const uint8_t *peerAddrIn, |
| rgrover1 | 527:493185cebc03 | 107 | AddressType_t ownAddrTypeIn, |
| rgrover1 | 527:493185cebc03 | 108 | const uint8_t *ownAddrIn, |
| rgrover1 | 527:493185cebc03 | 109 | const ConnectionParams_t *connectionParamsIn) : |
| rgrover1 | 527:493185cebc03 | 110 | handle(handleIn), |
| rgrover1 | 527:493185cebc03 | 111 | role(roleIn), |
| rgrover1 | 527:493185cebc03 | 112 | peerAddrType(peerAddrTypeIn), |
| rgrover1 | 527:493185cebc03 | 113 | peerAddr(), |
| rgrover1 | 527:493185cebc03 | 114 | ownAddrType(ownAddrTypeIn), |
| rgrover1 | 527:493185cebc03 | 115 | ownAddr(), |
| rgrover1 | 527:493185cebc03 | 116 | connectionParams(connectionParamsIn) { |
| rgrover1 | 527:493185cebc03 | 117 | memcpy(peerAddr, peerAddrIn, ADDR_LEN); |
| rgrover1 | 527:493185cebc03 | 118 | memcpy(ownAddr, ownAddrIn, ADDR_LEN); |
| rgrover1 | 527:493185cebc03 | 119 | } |
| rgrover1 | 527:493185cebc03 | 120 | }; |
| rgrover1 | 527:493185cebc03 | 121 | |
| rgrover1 | 360:7d37e1adef33 | 122 | enum SecurityMode_t { |
| rgrover1 | 361:9686f5c882fa | 123 | SECURITY_MODE_NO_ACCESS, |
| rgrover1 | 372:0db007a23f71 | 124 | SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */ |
| rgrover1 | 372:0db007a23f71 | 125 | SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */ |
| rgrover1 | 372:0db007a23f71 | 126 | SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */ |
| rgrover1 | 372:0db007a23f71 | 127 | SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */ |
| rgrover1 | 372:0db007a23f71 | 128 | SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */ |
| rgrover1 | 360:7d37e1adef33 | 129 | }; |
| rgrover1 | 360:7d37e1adef33 | 130 | |
| rgrover1 | 352:79d7cb60ae27 | 131 | /** |
| rgrover1 | 352:79d7cb60ae27 | 132 | * @brief Defines possible security status/states. |
| rgrover1 | 352:79d7cb60ae27 | 133 | * |
| rgrover1 | 352:79d7cb60ae27 | 134 | * @details Defines possible security status/states of a link when requested by getLinkSecurity(). |
| rgrover1 | 352:79d7cb60ae27 | 135 | */ |
| rgrover1 | 352:79d7cb60ae27 | 136 | enum LinkSecurityStatus_t { |
| rgrover1 | 352:79d7cb60ae27 | 137 | NOT_ENCRYPTED, /**< The link is not secured. */ |
| rgrover1 | 352:79d7cb60ae27 | 138 | ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ |
| rgrover1 | 352:79d7cb60ae27 | 139 | ENCRYPTED /**< The link is secure.*/ |
| rgrover1 | 352:79d7cb60ae27 | 140 | }; |
| rgrover1 | 352:79d7cb60ae27 | 141 | |
| rgrover1 | 357:d4bb5d2b837a | 142 | enum SecurityIOCapabilities_t { |
| rgrover1 | 357:d4bb5d2b837a | 143 | IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */ |
| rgrover1 | 357:d4bb5d2b837a | 144 | IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */ |
| rgrover1 | 357:d4bb5d2b837a | 145 | IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */ |
| rgrover1 | 357:d4bb5d2b837a | 146 | IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ |
| rgrover1 | 357:d4bb5d2b837a | 147 | IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */ |
| rgrover1 | 357:d4bb5d2b837a | 148 | }; |
| rgrover1 | 357:d4bb5d2b837a | 149 | |
| rgrover1 | 359:611485c370f5 | 150 | enum SecurityCompletionStatus_t { |
| rgrover1 | 359:611485c370f5 | 151 | SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ |
| rgrover1 | 359:611485c370f5 | 152 | SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ |
| rgrover1 | 359:611485c370f5 | 153 | SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ |
| rgrover1 | 367:c3f4ad55ed33 | 154 | SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ |
| rgrover1 | 359:611485c370f5 | 155 | SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ |
| rgrover1 | 359:611485c370f5 | 156 | SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ |
| rgrover1 | 359:611485c370f5 | 157 | SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ |
| rgrover1 | 359:611485c370f5 | 158 | SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ |
| rgrover1 | 359:611485c370f5 | 159 | SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ |
| rgrover1 | 359:611485c370f5 | 160 | SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ |
| rgrover1 | 359:611485c370f5 | 161 | SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ |
| rgrover1 | 359:611485c370f5 | 162 | SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ |
| rgrover1 | 359:611485c370f5 | 163 | SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ |
| rgrover1 | 359:611485c370f5 | 164 | }; |
| rgrover1 | 359:611485c370f5 | 165 | |
| rgrover1 | 357:d4bb5d2b837a | 166 | /** |
| rgrover1 | 357:d4bb5d2b837a | 167 | * Declaration of type containing a passkey to be used during pairing. This |
| rgrover1 | 357:d4bb5d2b837a | 168 | * is passed into initializeSecurity() to specify a pre-programmed passkey |
| rgrover1 | 357:d4bb5d2b837a | 169 | * for authentication instead of generating a random one. |
| rgrover1 | 357:d4bb5d2b837a | 170 | */ |
| rgrover1 | 357:d4bb5d2b837a | 171 | static const unsigned PASSKEY_LEN = 6; |
| rgrover1 | 357:d4bb5d2b837a | 172 | typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ |
| rgrover1 | 357:d4bb5d2b837a | 173 | |
| rgrover1 | 260:ea7f9f14cc15 | 174 | static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */ |
| rgrover1 | 398:9d7666c2305f | 175 | static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */ |
| rgrover1 | 260:ea7f9f14cc15 | 176 | static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) { |
| rgrover1 | 260:ea7f9f14cc15 | 177 | return (durationInMillis * 1000) / UNIT_1_25_MS; |
| rgrover1 | 260:ea7f9f14cc15 | 178 | } |
| rgrover1 | 260:ea7f9f14cc15 | 179 | static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) { |
| rgrover1 | 260:ea7f9f14cc15 | 180 | return (durationInMillis * 1000) / UNIT_0_625_MS; |
| rgrover1 | 260:ea7f9f14cc15 | 181 | } |
| rgrover1 | 399:1a69d53f00cc | 182 | static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits) { |
| rgrover1 | 325:501ad8b8bbe5 | 183 | return (gapUnits * UNIT_0_625_MS) / 1000; |
| rgrover1 | 325:501ad8b8bbe5 | 184 | } |
| rgrover1 | 260:ea7f9f14cc15 | 185 | |
| rgrover1 | 260:ea7f9f14cc15 | 186 | typedef void (*EventCallback_t)(void); |
| rgrover1 | 527:493185cebc03 | 187 | typedef void (*ConnectionEventCallback_t)(const ConnectionCallbackParams_t *params); |
| rgrover1 | 349:b8b2b3973c47 | 188 | typedef void (*HandleSpecificEvent_t)(Handle_t handle); |
| rgrover1 | 260:ea7f9f14cc15 | 189 | typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t); |
| rgrover1 | 341:8a104d9d80c1 | 190 | typedef void (*RadioNotificationEventCallback_t) (bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */ |
| rgrover1 | 363:a3d59a6e5da0 | 191 | typedef void (*SecuritySetupInitiatedCallback_t)(Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); |
| rgrover1 | 363:a3d59a6e5da0 | 192 | typedef void (*SecuritySetupCompletedCallback_t)(Handle_t, SecurityCompletionStatus_t status); |
| rgrover1 | 362:3b1ff00ad8a4 | 193 | typedef void (*LinkSecuredCallback_t)(Handle_t handle, SecurityMode_t securityMode); |
| rgrover1 | 369:9a76cc068644 | 194 | typedef void (*PasskeyDisplayCallback_t)(Handle_t handle, const Passkey_t passkey); |
| rgrover1 | 260:ea7f9f14cc15 | 195 | |
| rgrover1 | 537:00d5affbb2b2 | 196 | /* |
| rgrover1 | 537:00d5affbb2b2 | 197 | * These functions must be defined in the platform-specific sub-class. |
| rgrover1 | 537:00d5affbb2b2 | 198 | */ |
| rgrover1 | 526:caa67c3187a0 | 199 | public: |
| rgrover1 | 537:00d5affbb2b2 | 200 | /** |
| rgrover1 | 537:00d5affbb2b2 | 201 | * Set the BTLE MAC address and type. Please note that the address format is |
| rgrover1 | 537:00d5affbb2b2 | 202 | * LSB (least significant byte first). Please refer to Address_t. |
| rgrover1 | 537:00d5affbb2b2 | 203 | * |
| rgrover1 | 537:00d5affbb2b2 | 204 | * @return BLE_ERROR_NONE on success. |
| rgrover1 | 537:00d5affbb2b2 | 205 | */ |
| rgrover1 | 537:00d5affbb2b2 | 206 | virtual ble_error_t setAddress(AddressType_t type, const Address_t address) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 207 | |
| rgrover1 | 537:00d5affbb2b2 | 208 | /** |
| rgrover1 | 537:00d5affbb2b2 | 209 | * Fetch the BTLE MAC address and type. |
| rgrover1 | 537:00d5affbb2b2 | 210 | * |
| rgrover1 | 537:00d5affbb2b2 | 211 | * @return BLE_ERROR_NONE on success. |
| rgrover1 | 537:00d5affbb2b2 | 212 | */ |
| rgrover1 | 537:00d5affbb2b2 | 213 | virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 214 | |
| rgrover1 | 537:00d5affbb2b2 | 215 | /** |
| rgrover1 | 537:00d5affbb2b2 | 216 | * @return Minimum Advertising interval in milliseconds. |
| rgrover1 | 537:00d5affbb2b2 | 217 | */ |
| rgrover1 | 537:00d5affbb2b2 | 218 | virtual uint16_t getMinAdvertisingInterval(void) const = 0; |
| rgrover1 | 537:00d5affbb2b2 | 219 | |
| rgrover1 | 537:00d5affbb2b2 | 220 | /** |
| rgrover1 | 537:00d5affbb2b2 | 221 | * @return Minimum Advertising interval in milliseconds for non-connectible mode. |
| rgrover1 | 537:00d5affbb2b2 | 222 | */ |
| rgrover1 | 537:00d5affbb2b2 | 223 | virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const = 0; |
| rgrover1 | 537:00d5affbb2b2 | 224 | |
| rgrover1 | 537:00d5affbb2b2 | 225 | /** |
| rgrover1 | 537:00d5affbb2b2 | 226 | * @return Maximum Advertising interval in milliseconds. |
| rgrover1 | 537:00d5affbb2b2 | 227 | */ |
| rgrover1 | 537:00d5affbb2b2 | 228 | virtual uint16_t getMaxAdvertisingInterval(void) const = 0; |
| rgrover1 | 537:00d5affbb2b2 | 229 | |
| rgrover1 | 537:00d5affbb2b2 | 230 | virtual ble_error_t stopAdvertising(void) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 231 | |
| rgrover1 | 537:00d5affbb2b2 | 232 | /** |
| rgrover1 | 537:00d5affbb2b2 | 233 | * Stop scanning. The current scanning parameters remain in effect. |
| rgrover1 | 537:00d5affbb2b2 | 234 | * |
| rgrover1 | 537:00d5affbb2b2 | 235 | * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. |
| rgrover1 | 537:00d5affbb2b2 | 236 | */ |
| rgrover1 | 537:00d5affbb2b2 | 237 | virtual ble_error_t stopScan() = 0; |
| rgrover1 | 537:00d5affbb2b2 | 238 | |
| rgrover1 | 537:00d5affbb2b2 | 239 | /** |
| rgrover1 | 537:00d5affbb2b2 | 240 | * Create a connection (GAP Link Establishment). |
| rgrover1 | 537:00d5affbb2b2 | 241 | * |
| rgrover1 | 537:00d5affbb2b2 | 242 | * @param peerAddr |
| rgrover1 | 537:00d5affbb2b2 | 243 | * 48-bit address, LSB format. |
| rgrover1 | 537:00d5affbb2b2 | 244 | * @param peerAddrType |
| rgrover1 | 537:00d5affbb2b2 | 245 | * Address type of the peer. |
| rgrover1 | 537:00d5affbb2b2 | 246 | * @param connectionParams |
| rgrover1 | 537:00d5affbb2b2 | 247 | * Connection parameters. |
| rgrover1 | 537:00d5affbb2b2 | 248 | * @param scanParams |
| rgrover1 | 537:00d5affbb2b2 | 249 | * Paramters to be used while scanning for the peer. |
| rgrover1 | 537:00d5affbb2b2 | 250 | * @return BLE_ERROR_NONE if connection establishment procedure is started |
| rgrover1 | 537:00d5affbb2b2 | 251 | * successfully. The onConnection callback (if set) will be invoked upon |
| rgrover1 | 537:00d5affbb2b2 | 252 | * a connection event. |
| rgrover1 | 537:00d5affbb2b2 | 253 | */ |
| rgrover1 | 527:493185cebc03 | 254 | virtual ble_error_t connect(const Address_t peerAddr, |
| rgrover1 | 527:493185cebc03 | 255 | Gap::AddressType_t peerAddrType, |
| rgrover1 | 527:493185cebc03 | 256 | const ConnectionParams_t *connectionParams, |
| rgrover1 | 527:493185cebc03 | 257 | const GapScanningParams *scanParams) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 258 | |
| rgrover1 | 537:00d5affbb2b2 | 259 | /** |
| rgrover1 | 537:00d5affbb2b2 | 260 | * This call initiates the disconnection procedure, and its completion will |
| rgrover1 | 537:00d5affbb2b2 | 261 | * be communicated to the application with an invocation of the |
| rgrover1 | 537:00d5affbb2b2 | 262 | * onDisconnection callback. |
| rgrover1 | 537:00d5affbb2b2 | 263 | * |
| rgrover1 | 537:00d5affbb2b2 | 264 | * @param reason |
| rgrover1 | 537:00d5affbb2b2 | 265 | * The reason for disconnection to be sent back to the peer. |
| rgrover1 | 537:00d5affbb2b2 | 266 | */ |
| rgrover1 | 537:00d5affbb2b2 | 267 | virtual ble_error_t disconnect(DisconnectionReason_t reason) = 0; |
| rgrover1 | 260:ea7f9f14cc15 | 268 | |
| rgrover1 | 537:00d5affbb2b2 | 269 | /** |
| rgrover1 | 537:00d5affbb2b2 | 270 | * Get the GAP peripheral preferred connection parameters. These are the |
| rgrover1 | 537:00d5affbb2b2 | 271 | * defaults that the peripheral would like to have in a connection. The |
| rgrover1 | 537:00d5affbb2b2 | 272 | * choice of the connection parameters is eventually up to the central. |
| rgrover1 | 537:00d5affbb2b2 | 273 | * |
| rgrover1 | 537:00d5affbb2b2 | 274 | * @param[out] params |
| rgrover1 | 537:00d5affbb2b2 | 275 | * The structure where the parameters will be stored. Memory |
| rgrover1 | 537:00d5affbb2b2 | 276 | * for this is owned by the caller. |
| rgrover1 | 537:00d5affbb2b2 | 277 | * |
| rgrover1 | 537:00d5affbb2b2 | 278 | * @return BLE_ERROR_NONE if the parameters were successfully filled into |
| rgrover1 | 537:00d5affbb2b2 | 279 | * the given structure pointed to by params. |
| rgrover1 | 537:00d5affbb2b2 | 280 | */ |
| rgrover1 | 537:00d5affbb2b2 | 281 | virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 282 | |
| rgrover1 | 537:00d5affbb2b2 | 283 | /** |
| rgrover1 | 537:00d5affbb2b2 | 284 | * Set the GAP peripheral preferred connection parameters. These are the |
| rgrover1 | 537:00d5affbb2b2 | 285 | * defaults that the peripheral would like to have in a connection. The |
| rgrover1 | 537:00d5affbb2b2 | 286 | * choice of the connection parameters is eventually up to the central. |
| rgrover1 | 537:00d5affbb2b2 | 287 | * |
| rgrover1 | 537:00d5affbb2b2 | 288 | * @param[in] params |
| rgrover1 | 537:00d5affbb2b2 | 289 | * The structure containing the desired parameters. |
| rgrover1 | 537:00d5affbb2b2 | 290 | */ |
| rgrover1 | 537:00d5affbb2b2 | 291 | virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 292 | |
| rgrover1 | 537:00d5affbb2b2 | 293 | /** |
| rgrover1 | 537:00d5affbb2b2 | 294 | * Update connection parameters while in the peripheral role. |
| rgrover1 | 537:00d5affbb2b2 | 295 | * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for |
| rgrover1 | 537:00d5affbb2b2 | 296 | * the central to perform the procedure. |
| rgrover1 | 537:00d5affbb2b2 | 297 | * @param[in] handle |
| rgrover1 | 537:00d5affbb2b2 | 298 | * Connection Handle |
| rgrover1 | 537:00d5affbb2b2 | 299 | * @param[in] params |
| rgrover1 | 537:00d5affbb2b2 | 300 | * Pointer to desired connection parameters. If NULL is provided on a peripheral role, |
| rgrover1 | 537:00d5affbb2b2 | 301 | * the parameters in the PPCP characteristic of the GAP service will be used instead. |
| rgrover1 | 537:00d5affbb2b2 | 302 | */ |
| rgrover1 | 537:00d5affbb2b2 | 303 | virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 304 | |
| rgrover1 | 537:00d5affbb2b2 | 305 | virtual ble_error_t purgeAllBondingState(void) = 0; |
| rgrover1 | 352:79d7cb60ae27 | 306 | virtual ble_error_t getLinkSecurity(Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) = 0; |
| rgrover1 | 352:79d7cb60ae27 | 307 | |
| rgrover1 | 537:00d5affbb2b2 | 308 | /** |
| rgrover1 | 537:00d5affbb2b2 | 309 | * Set the device name characteristic in the GAP service. |
| rgrover1 | 537:00d5affbb2b2 | 310 | * @param[in] deviceName |
| rgrover1 | 537:00d5affbb2b2 | 311 | * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. |
| rgrover1 | 537:00d5affbb2b2 | 312 | */ |
| rgrover1 | 537:00d5affbb2b2 | 313 | virtual ble_error_t setDeviceName(const uint8_t *deviceName) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 314 | |
| rgrover1 | 537:00d5affbb2b2 | 315 | /** |
| rgrover1 | 537:00d5affbb2b2 | 316 | * Get the value of the device name characteristic in the GAP service. |
| rgrover1 | 537:00d5affbb2b2 | 317 | * @param[out] deviceName |
| rgrover1 | 537:00d5affbb2b2 | 318 | * Pointer to an empty buffer where the UTF-8 *non NULL- |
| rgrover1 | 537:00d5affbb2b2 | 319 | * terminated* string will be placed. Set this |
| rgrover1 | 537:00d5affbb2b2 | 320 | * value to NULL in order to obtain the deviceName-length |
| rgrover1 | 537:00d5affbb2b2 | 321 | * from the 'length' parameter. |
| rgrover1 | 537:00d5affbb2b2 | 322 | * |
| rgrover1 | 537:00d5affbb2b2 | 323 | * @param[in/out] lengthP |
| rgrover1 | 537:00d5affbb2b2 | 324 | * (on input) Length of the buffer pointed to by deviceName; |
| rgrover1 | 537:00d5affbb2b2 | 325 | * (on output) the complete device name length (without the |
| rgrover1 | 537:00d5affbb2b2 | 326 | * null terminator). |
| rgrover1 | 537:00d5affbb2b2 | 327 | * |
| rgrover1 | 537:00d5affbb2b2 | 328 | * @note If the device name is longer than the size of the supplied buffer, |
| rgrover1 | 537:00d5affbb2b2 | 329 | * length will return the complete device name length, and not the |
| rgrover1 | 537:00d5affbb2b2 | 330 | * number of bytes actually returned in deviceName. The application may |
| rgrover1 | 537:00d5affbb2b2 | 331 | * use this information to retry with a suitable buffer size. |
| rgrover1 | 537:00d5affbb2b2 | 332 | */ |
| rgrover1 | 260:ea7f9f14cc15 | 333 | virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 334 | |
| rgrover1 | 537:00d5affbb2b2 | 335 | /** |
| rgrover1 | 537:00d5affbb2b2 | 336 | * Set the appearance characteristic in the GAP service. |
| rgrover1 | 537:00d5affbb2b2 | 337 | * @param[in] appearance |
| rgrover1 | 537:00d5affbb2b2 | 338 | * The new value for the device-appearance. |
| rgrover1 | 537:00d5affbb2b2 | 339 | */ |
| rgrover1 | 537:00d5affbb2b2 | 340 | virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 341 | |
| rgrover1 | 537:00d5affbb2b2 | 342 | /** |
| rgrover1 | 537:00d5affbb2b2 | 343 | * Get the appearance characteristic in the GAP service. |
| rgrover1 | 537:00d5affbb2b2 | 344 | * @param[out] appearance |
| rgrover1 | 537:00d5affbb2b2 | 345 | * The new value for the device-appearance. |
| rgrover1 | 537:00d5affbb2b2 | 346 | */ |
| rgrover1 | 537:00d5affbb2b2 | 347 | virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) = 0; |
| rgrover1 | 260:ea7f9f14cc15 | 348 | |
| rgrover1 | 537:00d5affbb2b2 | 349 | /** |
| rgrover1 | 537:00d5affbb2b2 | 350 | * Set the radio's transmit power. |
| rgrover1 | 537:00d5affbb2b2 | 351 | * @param[in] txPower Radio transmit power in dBm. |
| rgrover1 | 537:00d5affbb2b2 | 352 | */ |
| rgrover1 | 537:00d5affbb2b2 | 353 | virtual ble_error_t setTxPower(int8_t txPower) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 354 | |
| rgrover1 | 537:00d5affbb2b2 | 355 | /** |
| rgrover1 | 537:00d5affbb2b2 | 356 | * Query the underlying stack for permitted arguments for setTxPower(). |
| rgrover1 | 537:00d5affbb2b2 | 357 | * |
| rgrover1 | 537:00d5affbb2b2 | 358 | * @param[out] valueArrayPP |
| rgrover1 | 537:00d5affbb2b2 | 359 | * Out parameter to receive the immutable array of Tx values. |
| rgrover1 | 537:00d5affbb2b2 | 360 | * @param[out] countP |
| rgrover1 | 537:00d5affbb2b2 | 361 | * Out parameter to receive the array's size. |
| rgrover1 | 537:00d5affbb2b2 | 362 | */ |
| rgrover1 | 537:00d5affbb2b2 | 363 | virtual void getPermittedTxPowerValues(const int8_t **, size_t *) = 0; |
| rgrover1 | 526:caa67c3187a0 | 364 | |
| rgrover1 | 534:754131484cf1 | 365 | /* |
| rgrover1 | 537:00d5affbb2b2 | 366 | * APIs with non-virtual implementations. |
| rgrover1 | 534:754131484cf1 | 367 | */ |
| rgrover1 | 534:754131484cf1 | 368 | public: |
| rgrover1 | 537:00d5affbb2b2 | 369 | /** |
| rgrover1 | 537:00d5affbb2b2 | 370 | * Returns the current GAP state of the device using a bitmask which |
| rgrover1 | 537:00d5affbb2b2 | 371 | * describes whether the device is advertising and/or connected. |
| rgrover1 | 537:00d5affbb2b2 | 372 | */ |
| rgrover1 | 537:00d5affbb2b2 | 373 | GapState_t getState(void) const { |
| rgrover1 | 537:00d5affbb2b2 | 374 | return state; |
| rgrover1 | 537:00d5affbb2b2 | 375 | } |
| rgrover1 | 537:00d5affbb2b2 | 376 | |
| rgrover1 | 537:00d5affbb2b2 | 377 | /** |
| rgrover1 | 537:00d5affbb2b2 | 378 | * Set the GAP advertising mode to use for this device. |
| rgrover1 | 537:00d5affbb2b2 | 379 | */ |
| rgrover1 | 537:00d5affbb2b2 | 380 | void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) { |
| rgrover1 | 534:754131484cf1 | 381 | _advParams.setAdvertisingType(advType); |
| rgrover1 | 534:754131484cf1 | 382 | } |
| rgrover1 | 534:754131484cf1 | 383 | |
| rgrover1 | 537:00d5affbb2b2 | 384 | /** |
| rgrover1 | 537:00d5affbb2b2 | 385 | * @param[in] interval |
| rgrover1 | 537:00d5affbb2b2 | 386 | * Advertising interval in units of milliseconds. Advertising |
| rgrover1 | 537:00d5affbb2b2 | 387 | * is disabled if interval is 0. If interval is smaller than |
| rgrover1 | 537:00d5affbb2b2 | 388 | * the minimum supported value, then the minimum supported |
| rgrover1 | 537:00d5affbb2b2 | 389 | * value is used instead. This minimum value can be discovered |
| rgrover1 | 537:00d5affbb2b2 | 390 | * using getMinAdvertisingInterval(). |
| rgrover1 | 537:00d5affbb2b2 | 391 | * |
| rgrover1 | 537:00d5affbb2b2 | 392 | * This field must be set to 0 if connectionMode is equal |
| rgrover1 | 537:00d5affbb2b2 | 393 | * to ADV_CONNECTABLE_DIRECTED. |
| rgrover1 | 537:00d5affbb2b2 | 394 | * |
| rgrover1 | 537:00d5affbb2b2 | 395 | * @note: Decreasing this value will allow central devices to detect a |
| rgrover1 | 537:00d5affbb2b2 | 396 | * peripheral faster at the expense of more power being used by the radio |
| rgrover1 | 537:00d5affbb2b2 | 397 | * due to the higher data transmit rate. |
| rgrover1 | 537:00d5affbb2b2 | 398 | * |
| rgrover1 | 537:00d5affbb2b2 | 399 | * @note: This API is now *deprecated* and will be dropped in the future. |
| rgrover1 | 537:00d5affbb2b2 | 400 | * You should use the parallel API from Gap directly. A former call to |
| rgrover1 | 537:00d5affbb2b2 | 401 | * ble.setAdvertisingInterval(...) should now be achieved using |
| rgrover1 | 537:00d5affbb2b2 | 402 | * ble.gap().setAdvertisingInterval(...). |
| rgrover1 | 537:00d5affbb2b2 | 403 | * |
| rgrover1 | 537:00d5affbb2b2 | 404 | * @Note: [WARNING] This API previously used 0.625ms as the unit for its |
| rgrover1 | 537:00d5affbb2b2 | 405 | * 'interval' argument. That required an explicit conversion from |
| rgrover1 | 537:00d5affbb2b2 | 406 | * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is |
| rgrover1 | 537:00d5affbb2b2 | 407 | * no longer required as the new units are milliseconds. Any application |
| rgrover1 | 537:00d5affbb2b2 | 408 | * code depending on the old semantics would need to be updated accordingly. |
| rgrover1 | 537:00d5affbb2b2 | 409 | */ |
| rgrover1 | 534:754131484cf1 | 410 | void setAdvertisingInterval(uint16_t interval) { |
| rgrover1 | 534:754131484cf1 | 411 | if (interval == 0) { |
| rgrover1 | 534:754131484cf1 | 412 | stopAdvertising(); |
| rgrover1 | 534:754131484cf1 | 413 | } else if (interval < getMinAdvertisingInterval()) { |
| rgrover1 | 534:754131484cf1 | 414 | interval = getMinAdvertisingInterval(); |
| rgrover1 | 534:754131484cf1 | 415 | } |
| rgrover1 | 534:754131484cf1 | 416 | _advParams.setInterval(MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)); |
| rgrover1 | 534:754131484cf1 | 417 | } |
| rgrover1 | 534:754131484cf1 | 418 | |
| rgrover1 | 537:00d5affbb2b2 | 419 | /** |
| rgrover1 | 537:00d5affbb2b2 | 420 | * @param[in] timeout |
| rgrover1 | 537:00d5affbb2b2 | 421 | * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1 |
| rgrover1 | 537:00d5affbb2b2 | 422 | * and 16383). Use 0 to disable the advertising timeout. |
| rgrover1 | 537:00d5affbb2b2 | 423 | */ |
| rgrover1 | 537:00d5affbb2b2 | 424 | void setAdvertisingTimeout(uint16_t timeout) { |
| rgrover1 | 537:00d5affbb2b2 | 425 | _advParams.setTimeout(timeout); |
| rgrover1 | 537:00d5affbb2b2 | 426 | } |
| rgrover1 | 537:00d5affbb2b2 | 427 | |
| rgrover1 | 537:00d5affbb2b2 | 428 | /** |
| rgrover1 | 537:00d5affbb2b2 | 429 | * Start advertising. |
| rgrover1 | 537:00d5affbb2b2 | 430 | */ |
| rgrover1 | 531:bdcd44b03974 | 431 | ble_error_t startAdvertising(void) { |
| rgrover1 | 534:754131484cf1 | 432 | setAdvertisingData(); /* update the underlying stack */ |
| rgrover1 | 532:a709cfc1500d | 433 | return startAdvertising(_advParams); |
| rgrover1 | 531:bdcd44b03974 | 434 | } |
| rgrover1 | 531:bdcd44b03974 | 435 | |
| rgrover1 | 534:754131484cf1 | 436 | /** |
| rgrover1 | 534:754131484cf1 | 437 | * Reset any advertising payload prepared from prior calls to |
| rgrover1 | 537:00d5affbb2b2 | 438 | * accumulateAdvertisingPayload(). This automatically propagates the re- |
| rgrover1 | 537:00d5affbb2b2 | 439 | * initialized adv payload to the underlying stack. |
| rgrover1 | 534:754131484cf1 | 440 | * |
| rgrover1 | 534:754131484cf1 | 441 | * Note: This should be followed by a call to setAdvertisingPayload() or |
| rgrover1 | 534:754131484cf1 | 442 | * startAdvertising() before the update takes effect. |
| rgrover1 | 534:754131484cf1 | 443 | */ |
| rgrover1 | 534:754131484cf1 | 444 | void clearAdvertisingPayload(void) { |
| rgrover1 | 534:754131484cf1 | 445 | _advPayload.clear(); |
| rgrover1 | 537:00d5affbb2b2 | 446 | setAdvertisingData(); |
| rgrover1 | 534:754131484cf1 | 447 | } |
| rgrover1 | 534:754131484cf1 | 448 | |
| rgrover1 | 534:754131484cf1 | 449 | /** |
| rgrover1 | 534:754131484cf1 | 450 | * Accumulate an AD structure in the advertising payload. Please note that |
| rgrover1 | 534:754131484cf1 | 451 | * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used |
| rgrover1 | 534:754131484cf1 | 452 | * as an additional 31 bytes if the advertising payload proves to be too |
| rgrover1 | 534:754131484cf1 | 453 | * small. |
| rgrover1 | 534:754131484cf1 | 454 | * |
| rgrover1 | 537:00d5affbb2b2 | 455 | * @param[in] flags |
| rgrover1 | 537:00d5affbb2b2 | 456 | * The flags to be added. Please refer to |
| rgrover1 | 537:00d5affbb2b2 | 457 | * GapAdvertisingData::Flags for valid flags. Multiple |
| rgrover1 | 537:00d5affbb2b2 | 458 | * flags may be specified in combination. |
| rgrover1 | 534:754131484cf1 | 459 | */ |
| rgrover1 | 534:754131484cf1 | 460 | ble_error_t accumulateAdvertisingPayload(uint8_t flags) { |
| rgrover1 | 537:00d5affbb2b2 | 461 | ble_error_t rc; |
| rgrover1 | 537:00d5affbb2b2 | 462 | if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) { |
| rgrover1 | 537:00d5affbb2b2 | 463 | return rc; |
| rgrover1 | 537:00d5affbb2b2 | 464 | } |
| rgrover1 | 537:00d5affbb2b2 | 465 | |
| rgrover1 | 537:00d5affbb2b2 | 466 | return setAdvertisingData(); |
| rgrover1 | 534:754131484cf1 | 467 | } |
| rgrover1 | 534:754131484cf1 | 468 | |
| rgrover1 | 534:754131484cf1 | 469 | /** |
| rgrover1 | 534:754131484cf1 | 470 | * Accumulate an AD structure in the advertising payload. Please note that |
| rgrover1 | 534:754131484cf1 | 471 | * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used |
| rgrover1 | 534:754131484cf1 | 472 | * as an additional 31 bytes if the advertising payload proves to be too |
| rgrover1 | 534:754131484cf1 | 473 | * small. |
| rgrover1 | 534:754131484cf1 | 474 | * |
| rgrover1 | 534:754131484cf1 | 475 | * @param app |
| rgrover1 | 534:754131484cf1 | 476 | * The appearance of the peripheral. |
| rgrover1 | 534:754131484cf1 | 477 | */ |
| rgrover1 | 534:754131484cf1 | 478 | ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { |
| rgrover1 | 534:754131484cf1 | 479 | setAppearance(app); |
| rgrover1 | 537:00d5affbb2b2 | 480 | |
| rgrover1 | 537:00d5affbb2b2 | 481 | ble_error_t rc; |
| rgrover1 | 537:00d5affbb2b2 | 482 | if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) { |
| rgrover1 | 537:00d5affbb2b2 | 483 | return rc; |
| rgrover1 | 537:00d5affbb2b2 | 484 | } |
| rgrover1 | 537:00d5affbb2b2 | 485 | |
| rgrover1 | 537:00d5affbb2b2 | 486 | return setAdvertisingData(); |
| rgrover1 | 534:754131484cf1 | 487 | } |
| rgrover1 | 534:754131484cf1 | 488 | |
| rgrover1 | 534:754131484cf1 | 489 | /** |
| rgrover1 | 534:754131484cf1 | 490 | * Accumulate an AD structure in the advertising payload. Please note that |
| rgrover1 | 534:754131484cf1 | 491 | * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used |
| rgrover1 | 534:754131484cf1 | 492 | * as an additional 31 bytes if the advertising payload proves to be too |
| rgrover1 | 534:754131484cf1 | 493 | * small. |
| rgrover1 | 534:754131484cf1 | 494 | * |
| rgrover1 | 534:754131484cf1 | 495 | * @param app |
| rgrover1 | 534:754131484cf1 | 496 | * The max transmit power to be used by the controller. This is |
| rgrover1 | 534:754131484cf1 | 497 | * only a hint. |
| rgrover1 | 534:754131484cf1 | 498 | */ |
| rgrover1 | 534:754131484cf1 | 499 | ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { |
| rgrover1 | 537:00d5affbb2b2 | 500 | ble_error_t rc; |
| rgrover1 | 537:00d5affbb2b2 | 501 | if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) { |
| rgrover1 | 537:00d5affbb2b2 | 502 | return rc; |
| rgrover1 | 537:00d5affbb2b2 | 503 | } |
| rgrover1 | 537:00d5affbb2b2 | 504 | |
| rgrover1 | 537:00d5affbb2b2 | 505 | return setAdvertisingData(); |
| rgrover1 | 534:754131484cf1 | 506 | } |
| rgrover1 | 534:754131484cf1 | 507 | |
| rgrover1 | 534:754131484cf1 | 508 | /** |
| rgrover1 | 534:754131484cf1 | 509 | * Accumulate a variable length byte-stream as an AD structure in the |
| rgrover1 | 534:754131484cf1 | 510 | * advertising payload. Please note that the payload is limited to 31 bytes. |
| rgrover1 | 534:754131484cf1 | 511 | * The SCAN_RESPONSE message may be used as an additional 31 bytes if the |
| rgrover1 | 534:754131484cf1 | 512 | * advertising payload proves to be too small. |
| rgrover1 | 534:754131484cf1 | 513 | * |
| rgrover1 | 534:754131484cf1 | 514 | * @param type The type which describes the variable length data. |
| rgrover1 | 534:754131484cf1 | 515 | * @param data data bytes. |
| rgrover1 | 534:754131484cf1 | 516 | * @param len length of data. |
| rgrover1 | 534:754131484cf1 | 517 | */ |
| rgrover1 | 534:754131484cf1 | 518 | ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { |
| rgrover1 | 534:754131484cf1 | 519 | if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { |
| rgrover1 | 534:754131484cf1 | 520 | setDeviceName(data); |
| rgrover1 | 534:754131484cf1 | 521 | } |
| rgrover1 | 537:00d5affbb2b2 | 522 | |
| rgrover1 | 537:00d5affbb2b2 | 523 | ble_error_t rc; |
| rgrover1 | 537:00d5affbb2b2 | 524 | if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) { |
| rgrover1 | 537:00d5affbb2b2 | 525 | return rc; |
| rgrover1 | 537:00d5affbb2b2 | 526 | } |
| rgrover1 | 537:00d5affbb2b2 | 527 | |
| rgrover1 | 537:00d5affbb2b2 | 528 | return setAdvertisingData(); |
| rgrover1 | 537:00d5affbb2b2 | 529 | } |
| rgrover1 | 537:00d5affbb2b2 | 530 | |
| rgrover1 | 537:00d5affbb2b2 | 531 | /** |
| rgrover1 | 537:00d5affbb2b2 | 532 | * Setup a particular, user-constructed advertisement payload for the |
| rgrover1 | 537:00d5affbb2b2 | 533 | * underlying stack. It would be uncommon for this API to be used directly; |
| rgrover1 | 537:00d5affbb2b2 | 534 | * there are other APIs to build an advertisement payload (see above). |
| rgrover1 | 537:00d5affbb2b2 | 535 | */ |
| rgrover1 | 537:00d5affbb2b2 | 536 | ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) { |
| rgrover1 | 537:00d5affbb2b2 | 537 | _advPayload = payload; |
| rgrover1 | 537:00d5affbb2b2 | 538 | return setAdvertisingData(); |
| rgrover1 | 537:00d5affbb2b2 | 539 | } |
| rgrover1 | 537:00d5affbb2b2 | 540 | |
| rgrover1 | 537:00d5affbb2b2 | 541 | /** |
| rgrover1 | 537:00d5affbb2b2 | 542 | * @return Read back advertising data. Useful for storing and |
| rgrover1 | 537:00d5affbb2b2 | 543 | * restoring payload. |
| rgrover1 | 537:00d5affbb2b2 | 544 | */ |
| rgrover1 | 537:00d5affbb2b2 | 545 | const GapAdvertisingData &getAdvertisingPayload(void) const { |
| rgrover1 | 537:00d5affbb2b2 | 546 | return _advPayload; |
| rgrover1 | 534:754131484cf1 | 547 | } |
| rgrover1 | 534:754131484cf1 | 548 | |
| rgrover1 | 534:754131484cf1 | 549 | /** |
| rgrover1 | 534:754131484cf1 | 550 | * Accumulate a variable length byte-stream as an AD structure in the |
| rgrover1 | 534:754131484cf1 | 551 | * scanResponse payload. |
| rgrover1 | 534:754131484cf1 | 552 | * |
| rgrover1 | 537:00d5affbb2b2 | 553 | * @param[in] type The type which describes the variable length data. |
| rgrover1 | 537:00d5affbb2b2 | 554 | * @param[in] data data bytes. |
| rgrover1 | 537:00d5affbb2b2 | 555 | * @param[in] len length of data. |
| rgrover1 | 534:754131484cf1 | 556 | */ |
| rgrover1 | 534:754131484cf1 | 557 | ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { |
| rgrover1 | 537:00d5affbb2b2 | 558 | ble_error_t rc; |
| rgrover1 | 537:00d5affbb2b2 | 559 | if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) { |
| rgrover1 | 537:00d5affbb2b2 | 560 | return rc; |
| rgrover1 | 537:00d5affbb2b2 | 561 | } |
| rgrover1 | 537:00d5affbb2b2 | 562 | |
| rgrover1 | 537:00d5affbb2b2 | 563 | return setAdvertisingData(); |
| rgrover1 | 534:754131484cf1 | 564 | } |
| rgrover1 | 534:754131484cf1 | 565 | |
| rgrover1 | 534:754131484cf1 | 566 | /** |
| rgrover1 | 534:754131484cf1 | 567 | * Reset any scan response prepared from prior calls to |
| rgrover1 | 534:754131484cf1 | 568 | * accumulateScanResponse(). |
| rgrover1 | 534:754131484cf1 | 569 | * |
| rgrover1 | 534:754131484cf1 | 570 | * Note: This should be followed by a call to setAdvertisingPayload() or |
| rgrover1 | 534:754131484cf1 | 571 | * startAdvertising() before the update takes effect. |
| rgrover1 | 534:754131484cf1 | 572 | */ |
| rgrover1 | 534:754131484cf1 | 573 | void clearScanResponse(void) { |
| rgrover1 | 534:754131484cf1 | 574 | _scanResponse.clear(); |
| rgrover1 | 537:00d5affbb2b2 | 575 | setAdvertisingData(); |
| rgrover1 | 537:00d5affbb2b2 | 576 | } |
| rgrover1 | 537:00d5affbb2b2 | 577 | |
| rgrover1 | 537:00d5affbb2b2 | 578 | /** |
| rgrover1 | 537:00d5affbb2b2 | 579 | * Setup parameters for GAP scanning--i.e. observer mode. |
| rgrover1 | 537:00d5affbb2b2 | 580 | * @param[in] interval |
| rgrover1 | 537:00d5affbb2b2 | 581 | * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. |
| rgrover1 | 537:00d5affbb2b2 | 582 | * @param[in] window |
| rgrover1 | 537:00d5affbb2b2 | 583 | * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. |
| rgrover1 | 537:00d5affbb2b2 | 584 | * @param[in] timeout |
| rgrover1 | 537:00d5affbb2b2 | 585 | * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. |
| rgrover1 | 537:00d5affbb2b2 | 586 | * @param[in] activeScanning |
| rgrover1 | 537:00d5affbb2b2 | 587 | * Set to True if active-scanning is required. This is used to fetch the |
| rgrover1 | 537:00d5affbb2b2 | 588 | * scan response from a peer if possible. |
| rgrover1 | 537:00d5affbb2b2 | 589 | * |
| rgrover1 | 537:00d5affbb2b2 | 590 | * The scanning window divided by the interval determines the duty cycle for |
| rgrover1 | 537:00d5affbb2b2 | 591 | * scanning. For example, if the interval is 100ms and the window is 10ms, |
| rgrover1 | 537:00d5affbb2b2 | 592 | * then the controller will scan for 10 percent of the time. It is possible |
| rgrover1 | 537:00d5affbb2b2 | 593 | * to have the interval and window set to the same value. In this case, |
| rgrover1 | 537:00d5affbb2b2 | 594 | * scanning is continuous, with a change of scanning frequency once every |
| rgrover1 | 537:00d5affbb2b2 | 595 | * interval. |
| rgrover1 | 537:00d5affbb2b2 | 596 | * |
| rgrover1 | 537:00d5affbb2b2 | 597 | * Once the scanning parameters have been configured, scanning can be |
| rgrover1 | 537:00d5affbb2b2 | 598 | * enabled by using startScan(). |
| rgrover1 | 537:00d5affbb2b2 | 599 | * |
| rgrover1 | 537:00d5affbb2b2 | 600 | * @Note: The scan interval and window are recommendations to the BLE stack. |
| rgrover1 | 537:00d5affbb2b2 | 601 | */ |
| rgrover1 | 537:00d5affbb2b2 | 602 | ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, |
| rgrover1 | 537:00d5affbb2b2 | 603 | uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, |
| rgrover1 | 537:00d5affbb2b2 | 604 | uint16_t timeout = 0, |
| rgrover1 | 537:00d5affbb2b2 | 605 | bool activeScanning = false) { |
| rgrover1 | 537:00d5affbb2b2 | 606 | ble_error_t rc; |
| rgrover1 | 537:00d5affbb2b2 | 607 | if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && |
| rgrover1 | 537:00d5affbb2b2 | 608 | ((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) && |
| rgrover1 | 537:00d5affbb2b2 | 609 | ((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { |
| rgrover1 | 537:00d5affbb2b2 | 610 | _scanningParams.setActiveScanning(activeScanning); |
| rgrover1 | 537:00d5affbb2b2 | 611 | return BLE_ERROR_NONE; |
| rgrover1 | 537:00d5affbb2b2 | 612 | } |
| rgrover1 | 537:00d5affbb2b2 | 613 | |
| rgrover1 | 537:00d5affbb2b2 | 614 | return rc; |
| rgrover1 | 534:754131484cf1 | 615 | } |
| rgrover1 | 534:754131484cf1 | 616 | |
| rgrover1 | 537:00d5affbb2b2 | 617 | /** |
| rgrover1 | 537:00d5affbb2b2 | 618 | * Setup the scanInterval parameter for GAP scanning--i.e. observer mode. |
| rgrover1 | 537:00d5affbb2b2 | 619 | * @param[in] interval |
| rgrover1 | 537:00d5affbb2b2 | 620 | * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. |
| rgrover1 | 537:00d5affbb2b2 | 621 | * |
| rgrover1 | 537:00d5affbb2b2 | 622 | * The scanning window divided by the interval determines the duty cycle for |
| rgrover1 | 537:00d5affbb2b2 | 623 | * scanning. For example, if the interval is 100ms and the window is 10ms, |
| rgrover1 | 537:00d5affbb2b2 | 624 | * then the controller will scan for 10 percent of the time. It is possible |
| rgrover1 | 537:00d5affbb2b2 | 625 | * to have the interval and window set to the same value. In this case, |
| rgrover1 | 537:00d5affbb2b2 | 626 | * scanning is continuous, with a change of scanning frequency once every |
| rgrover1 | 537:00d5affbb2b2 | 627 | * interval. |
| rgrover1 | 537:00d5affbb2b2 | 628 | * |
| rgrover1 | 537:00d5affbb2b2 | 629 | * Once the scanning parameters have been configured, scanning can be |
| rgrover1 | 537:00d5affbb2b2 | 630 | * enabled by using startScan(). |
| rgrover1 | 537:00d5affbb2b2 | 631 | */ |
| rgrover1 | 537:00d5affbb2b2 | 632 | ble_error_t setScanInterval(uint16_t interval) { |
| rgrover1 | 537:00d5affbb2b2 | 633 | return _scanningParams.setInterval(interval); |
| rgrover1 | 537:00d5affbb2b2 | 634 | } |
| rgrover1 | 531:bdcd44b03974 | 635 | |
| rgrover1 | 537:00d5affbb2b2 | 636 | /** |
| rgrover1 | 537:00d5affbb2b2 | 637 | * Setup the scanWindow parameter for GAP scanning--i.e. observer mode. |
| rgrover1 | 537:00d5affbb2b2 | 638 | * @param[in] window |
| rgrover1 | 537:00d5affbb2b2 | 639 | * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. |
| rgrover1 | 537:00d5affbb2b2 | 640 | * |
| rgrover1 | 537:00d5affbb2b2 | 641 | * The scanning window divided by the interval determines the duty cycle for |
| rgrover1 | 537:00d5affbb2b2 | 642 | * scanning. For example, if the interval is 100ms and the window is 10ms, |
| rgrover1 | 537:00d5affbb2b2 | 643 | * then the controller will scan for 10 percent of the time. It is possible |
| rgrover1 | 537:00d5affbb2b2 | 644 | * to have the interval and window set to the same value. In this case, |
| rgrover1 | 537:00d5affbb2b2 | 645 | * scanning is continuous, with a change of scanning frequency once every |
| rgrover1 | 537:00d5affbb2b2 | 646 | * interval. |
| rgrover1 | 537:00d5affbb2b2 | 647 | * |
| rgrover1 | 537:00d5affbb2b2 | 648 | * Once the scanning parameters have been configured, scanning can be |
| rgrover1 | 537:00d5affbb2b2 | 649 | * enabled by using startScan(). |
| rgrover1 | 537:00d5affbb2b2 | 650 | */ |
| rgrover1 | 537:00d5affbb2b2 | 651 | ble_error_t setScanWindow(uint16_t window) { |
| rgrover1 | 537:00d5affbb2b2 | 652 | return _scanningParams.setWindow(window); |
| rgrover1 | 537:00d5affbb2b2 | 653 | } |
| rgrover1 | 537:00d5affbb2b2 | 654 | |
| rgrover1 | 537:00d5affbb2b2 | 655 | /** |
| rgrover1 | 537:00d5affbb2b2 | 656 | * Setup parameters for GAP scanning--i.e. observer mode. |
| rgrover1 | 537:00d5affbb2b2 | 657 | * @param[in] timeout |
| rgrover1 | 537:00d5affbb2b2 | 658 | * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. |
| rgrover1 | 537:00d5affbb2b2 | 659 | * |
| rgrover1 | 537:00d5affbb2b2 | 660 | * Once the scanning parameters have been configured, scanning can be |
| rgrover1 | 537:00d5affbb2b2 | 661 | * enabled by using startScan(). |
| rgrover1 | 537:00d5affbb2b2 | 662 | */ |
| rgrover1 | 537:00d5affbb2b2 | 663 | ble_error_t setScanTimeout(uint16_t timeout) { |
| rgrover1 | 537:00d5affbb2b2 | 664 | return _scanningParams.setTimeout(timeout); |
| rgrover1 | 537:00d5affbb2b2 | 665 | } |
| rgrover1 | 537:00d5affbb2b2 | 666 | |
| rgrover1 | 537:00d5affbb2b2 | 667 | /** |
| rgrover1 | 537:00d5affbb2b2 | 668 | * Setup parameters for GAP scanning--i.e. observer mode. |
| rgrover1 | 537:00d5affbb2b2 | 669 | * @param[in] activeScanning |
| rgrover1 | 537:00d5affbb2b2 | 670 | * Set to True if active-scanning is required. This is used to fetch the |
| rgrover1 | 537:00d5affbb2b2 | 671 | * scan response from a peer if possible. |
| rgrover1 | 537:00d5affbb2b2 | 672 | * |
| rgrover1 | 537:00d5affbb2b2 | 673 | * Once the scanning parameters have been configured, scanning can be |
| rgrover1 | 537:00d5affbb2b2 | 674 | * enabled by using startScan(). |
| rgrover1 | 537:00d5affbb2b2 | 675 | */ |
| rgrover1 | 537:00d5affbb2b2 | 676 | void setActiveScanning(bool activeScanning) { |
| rgrover1 | 537:00d5affbb2b2 | 677 | _scanningParams.setActiveScanning(activeScanning); |
| rgrover1 | 537:00d5affbb2b2 | 678 | } |
| rgrover1 | 537:00d5affbb2b2 | 679 | |
| rgrover1 | 537:00d5affbb2b2 | 680 | /** |
| rgrover1 | 537:00d5affbb2b2 | 681 | * Start scanning (Observer Procedure) based on the parameters currently in |
| rgrover1 | 537:00d5affbb2b2 | 682 | * effect. |
| rgrover1 | 537:00d5affbb2b2 | 683 | * |
| rgrover1 | 537:00d5affbb2b2 | 684 | * @param[in] callback |
| rgrover1 | 537:00d5affbb2b2 | 685 | * The application specific callback to be invoked upon |
| rgrover1 | 537:00d5affbb2b2 | 686 | * receiving every advertisement report. This can be passed in |
| rgrover1 | 537:00d5affbb2b2 | 687 | * as NULL, in which case scanning may not be enabled at all. |
| rgrover1 | 537:00d5affbb2b2 | 688 | */ |
| rgrover1 | 531:bdcd44b03974 | 689 | ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) { |
| rgrover1 | 407:ca6b956b33d1 | 690 | ble_error_t err = BLE_ERROR_NONE; |
| rgrover1 | 407:ca6b956b33d1 | 691 | if (callback) { |
| rgrover1 | 532:a709cfc1500d | 692 | if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { |
| rgrover1 | 407:ca6b956b33d1 | 693 | onAdvertisementReport.attach(callback); |
| rgrover1 | 407:ca6b956b33d1 | 694 | } |
| rgrover1 | 407:ca6b956b33d1 | 695 | } |
| rgrover1 | 407:ca6b956b33d1 | 696 | |
| rgrover1 | 407:ca6b956b33d1 | 697 | return err; |
| rgrover1 | 407:ca6b956b33d1 | 698 | } |
| rgrover1 | 407:ca6b956b33d1 | 699 | |
| rgrover1 | 537:00d5affbb2b2 | 700 | /** |
| rgrover1 | 537:00d5affbb2b2 | 701 | * Same as above, but this takes an (object, method) pair for a callback. |
| rgrover1 | 537:00d5affbb2b2 | 702 | */ |
| rgrover1 | 407:ca6b956b33d1 | 703 | template<typename T> |
| rgrover1 | 531:bdcd44b03974 | 704 | ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) { |
| rgrover1 | 407:ca6b956b33d1 | 705 | ble_error_t err = BLE_ERROR_NONE; |
| rgrover1 | 407:ca6b956b33d1 | 706 | if (object && callbackMember) { |
| rgrover1 | 532:a709cfc1500d | 707 | if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { |
| rgrover1 | 407:ca6b956b33d1 | 708 | onAdvertisementReport.attach(object, callbackMember); |
| rgrover1 | 407:ca6b956b33d1 | 709 | } |
| rgrover1 | 407:ca6b956b33d1 | 710 | } |
| rgrover1 | 407:ca6b956b33d1 | 711 | |
| rgrover1 | 407:ca6b956b33d1 | 712 | return err; |
| rgrover1 | 407:ca6b956b33d1 | 713 | } |
| rgrover1 | 407:ca6b956b33d1 | 714 | |
| rgrover1 | 537:00d5affbb2b2 | 715 | private: |
| rgrover1 | 537:00d5affbb2b2 | 716 | ble_error_t setAdvertisingData(void) { |
| rgrover1 | 537:00d5affbb2b2 | 717 | return setAdvertisingData(_advPayload, _scanResponse); |
| rgrover1 | 537:00d5affbb2b2 | 718 | } |
| rgrover1 | 537:00d5affbb2b2 | 719 | |
| rgrover1 | 537:00d5affbb2b2 | 720 | private: |
| rgrover1 | 537:00d5affbb2b2 | 721 | virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 722 | virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; |
| rgrover1 | 537:00d5affbb2b2 | 723 | |
| rgrover1 | 537:00d5affbb2b2 | 724 | public: |
| rgrover1 | 537:00d5affbb2b2 | 725 | /** |
| rgrover1 | 537:00d5affbb2b2 | 726 | * Accessors to read back currently active advertising params. |
| rgrover1 | 537:00d5affbb2b2 | 727 | */ |
| rgrover1 | 537:00d5affbb2b2 | 728 | GapAdvertisingParams &getAdvertisingParams(void) { |
| rgrover1 | 537:00d5affbb2b2 | 729 | return _advParams; |
| rgrover1 | 537:00d5affbb2b2 | 730 | } |
| rgrover1 | 537:00d5affbb2b2 | 731 | const GapAdvertisingParams &getAdvertisingParams(void) const { |
| rgrover1 | 537:00d5affbb2b2 | 732 | return _advParams; |
| rgrover1 | 537:00d5affbb2b2 | 733 | } |
| rgrover1 | 537:00d5affbb2b2 | 734 | |
| rgrover1 | 537:00d5affbb2b2 | 735 | /** |
| rgrover1 | 537:00d5affbb2b2 | 736 | * Setup a particular, user-constructed set of advertisement parameters for |
| rgrover1 | 537:00d5affbb2b2 | 737 | * the underlying stack. It would be uncommon for this API to be used |
| rgrover1 | 537:00d5affbb2b2 | 738 | * directly; there are other APIs to tweak advertisement parameters |
| rgrover1 | 537:00d5affbb2b2 | 739 | * individually. |
| rgrover1 | 537:00d5affbb2b2 | 740 | */ |
| rgrover1 | 537:00d5affbb2b2 | 741 | void setAdvertisingParams(const GapAdvertisingParams &newParams) { |
| rgrover1 | 537:00d5affbb2b2 | 742 | _advParams = newParams; |
| rgrover1 | 537:00d5affbb2b2 | 743 | } |
| rgrover1 | 537:00d5affbb2b2 | 744 | |
| rgrover1 | 526:caa67c3187a0 | 745 | public: |
| rgrover1 | 407:ca6b956b33d1 | 746 | virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) = 0; |
| rgrover1 | 407:ca6b956b33d1 | 747 | |
| rgrover1 | 260:ea7f9f14cc15 | 748 | /* Event callback handlers */ |
| rgrover1 | 260:ea7f9f14cc15 | 749 | void setOnTimeout(EventCallback_t callback) {onTimeout = callback;} |
| rgrover1 | 260:ea7f9f14cc15 | 750 | void setOnConnection(ConnectionEventCallback_t callback) {onConnection = callback;} |
| rgrover1 | 260:ea7f9f14cc15 | 751 | |
| rgrover1 | 260:ea7f9f14cc15 | 752 | /** |
| rgrover1 | 260:ea7f9f14cc15 | 753 | * Set the application callback for disconnection events. |
| rgrover1 | 260:ea7f9f14cc15 | 754 | * @param callback |
| rgrover1 | 260:ea7f9f14cc15 | 755 | * Pointer to the unique callback. |
| rgrover1 | 260:ea7f9f14cc15 | 756 | */ |
| rgrover1 | 260:ea7f9f14cc15 | 757 | void setOnDisconnection(DisconnectionEventCallback_t callback) {onDisconnection = callback;} |
| rgrover1 | 260:ea7f9f14cc15 | 758 | |
| rgrover1 | 260:ea7f9f14cc15 | 759 | /** |
| rgrover1 | 341:8a104d9d80c1 | 760 | * Set the application callback for radio-notification events. |
| rgrover1 | 341:8a104d9d80c1 | 761 | * @param callback |
| rgrover1 | 367:c3f4ad55ed33 | 762 | * Handler to be executed in response to a radio notification event. |
| rgrover1 | 341:8a104d9d80c1 | 763 | */ |
| rgrover1 | 341:8a104d9d80c1 | 764 | virtual void setOnRadioNotification(RadioNotificationEventCallback_t callback) {onRadioNotification = callback;} |
| rgrover1 | 341:8a104d9d80c1 | 765 | |
| rgrover1 | 341:8a104d9d80c1 | 766 | /** |
| rgrover1 | 349:b8b2b3973c47 | 767 | * To indicate that security procedure for link has started. |
| rgrover1 | 349:b8b2b3973c47 | 768 | */ |
| rgrover1 | 364:03a7a439a3bf | 769 | virtual void setOnSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {onSecuritySetupInitiated = callback;} |
| rgrover1 | 349:b8b2b3973c47 | 770 | |
| rgrover1 | 349:b8b2b3973c47 | 771 | /** |
| rgrover1 | 349:b8b2b3973c47 | 772 | * To indicate that security procedure for link has completed. |
| rgrover1 | 349:b8b2b3973c47 | 773 | */ |
| rgrover1 | 364:03a7a439a3bf | 774 | virtual void setOnSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {onSecuritySetupCompleted = callback;} |
| rgrover1 | 349:b8b2b3973c47 | 775 | |
| rgrover1 | 349:b8b2b3973c47 | 776 | /** |
| rgrover1 | 349:b8b2b3973c47 | 777 | * To indicate that link with the peer is secured. For bonded devices, |
| rgrover1 | 367:c3f4ad55ed33 | 778 | * subsequent re-connections with bonded peer will result only in this callback |
| rgrover1 | 349:b8b2b3973c47 | 779 | * when the link is secured and setup procedures will not occur unless the |
| rgrover1 | 349:b8b2b3973c47 | 780 | * bonding information is either lost or deleted on either or both sides. |
| rgrover1 | 349:b8b2b3973c47 | 781 | */ |
| rgrover1 | 362:3b1ff00ad8a4 | 782 | virtual void setOnLinkSecured(LinkSecuredCallback_t callback) {onLinkSecured = callback;} |
| rgrover1 | 349:b8b2b3973c47 | 783 | |
| rgrover1 | 349:b8b2b3973c47 | 784 | /** |
| rgrover1 | 349:b8b2b3973c47 | 785 | * To indicate that device context is stored persistently. |
| rgrover1 | 349:b8b2b3973c47 | 786 | */ |
| rgrover1 | 349:b8b2b3973c47 | 787 | virtual void setOnSecurityContextStored(HandleSpecificEvent_t callback) {onSecurityContextStored = callback;} |
| rgrover1 | 349:b8b2b3973c47 | 788 | |
| rgrover1 | 349:b8b2b3973c47 | 789 | /** |
| rgrover1 | 369:9a76cc068644 | 790 | * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. |
| rgrover1 | 369:9a76cc068644 | 791 | */ |
| rgrover1 | 369:9a76cc068644 | 792 | virtual void setOnPasskeyDisplay(PasskeyDisplayCallback_t callback) {onPasskeyDisplay = callback;} |
| rgrover1 | 369:9a76cc068644 | 793 | |
| rgrover1 | 369:9a76cc068644 | 794 | /** |
| rgrover1 | 260:ea7f9f14cc15 | 795 | * Append to a chain of callbacks to be invoked upon disconnection; these |
| rgrover1 | 260:ea7f9f14cc15 | 796 | * callbacks receive no context and are therefore different from the |
| rgrover1 | 260:ea7f9f14cc15 | 797 | * onDisconnection callback. |
| rgrover1 | 260:ea7f9f14cc15 | 798 | * @param callback |
| rgrover1 | 260:ea7f9f14cc15 | 799 | * function pointer to be invoked upon disconnection; receives no context. |
| rgrover1 | 260:ea7f9f14cc15 | 800 | * |
| rgrover1 | 260:ea7f9f14cc15 | 801 | * @note the disconnection CallChain should have been merged with |
| rgrover1 | 260:ea7f9f14cc15 | 802 | * onDisconnctionCallback; but this was not possible because |
| rgrover1 | 260:ea7f9f14cc15 | 803 | * FunctionPointer (which is a building block for CallChain) doesn't |
| rgrover1 | 260:ea7f9f14cc15 | 804 | * accept variadic templates. |
| rgrover1 | 260:ea7f9f14cc15 | 805 | */ |
| rgrover1 | 260:ea7f9f14cc15 | 806 | template<typename T> |
| rgrover1 | 260:ea7f9f14cc15 | 807 | void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) {disconnectionCallChain.add(tptr, mptr);} |
| rgrover1 | 260:ea7f9f14cc15 | 808 | |
| rgrover1 | 260:ea7f9f14cc15 | 809 | protected: |
| rgrover1 | 349:b8b2b3973c47 | 810 | Gap() : |
| rgrover1 | 532:a709cfc1500d | 811 | _advParams(), |
| rgrover1 | 532:a709cfc1500d | 812 | _advPayload(), |
| rgrover1 | 532:a709cfc1500d | 813 | _scanningParams(), |
| rgrover1 | 532:a709cfc1500d | 814 | _scanResponse(), |
| rgrover1 | 349:b8b2b3973c47 | 815 | state(), |
| rgrover1 | 349:b8b2b3973c47 | 816 | onTimeout(NULL), |
| rgrover1 | 349:b8b2b3973c47 | 817 | onConnection(NULL), |
| rgrover1 | 349:b8b2b3973c47 | 818 | onDisconnection(NULL), |
| rgrover1 | 349:b8b2b3973c47 | 819 | onRadioNotification(), |
| rgrover1 | 364:03a7a439a3bf | 820 | onSecuritySetupInitiated(), |
| rgrover1 | 364:03a7a439a3bf | 821 | onSecuritySetupCompleted(), |
| rgrover1 | 349:b8b2b3973c47 | 822 | onLinkSecured(), |
| rgrover1 | 349:b8b2b3973c47 | 823 | onSecurityContextStored(), |
| rgrover1 | 369:9a76cc068644 | 824 | onPasskeyDisplay(), |
| rgrover1 | 382:dcd0428dadb0 | 825 | onAdvertisementReport(), |
| rgrover1 | 349:b8b2b3973c47 | 826 | disconnectionCallChain() { |
| rgrover1 | 532:a709cfc1500d | 827 | _advPayload.clear(); |
| rgrover1 | 532:a709cfc1500d | 828 | _scanResponse.clear(); |
| rgrover1 | 260:ea7f9f14cc15 | 829 | } |
| rgrover1 | 260:ea7f9f14cc15 | 830 | |
| rgrover1 | 260:ea7f9f14cc15 | 831 | public: |
| rgrover1 | 527:493185cebc03 | 832 | void processConnectionEvent(Handle_t handle, |
| rgrover1 | 527:493185cebc03 | 833 | Role_t role, |
| rgrover1 | 527:493185cebc03 | 834 | AddressType_t peerAddrType, |
| rgrover1 | 527:493185cebc03 | 835 | const Address_t peerAddr, |
| rgrover1 | 527:493185cebc03 | 836 | AddressType_t ownAddrType, |
| rgrover1 | 527:493185cebc03 | 837 | const Address_t ownAddr, |
| rgrover1 | 527:493185cebc03 | 838 | const ConnectionParams_t *connectionParams) { |
| rgrover1 | 260:ea7f9f14cc15 | 839 | state.connected = 1; |
| rgrover1 | 260:ea7f9f14cc15 | 840 | if (onConnection) { |
| rgrover1 | 527:493185cebc03 | 841 | ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); |
| rgrover1 | 527:493185cebc03 | 842 | onConnection(&callbackParams); |
| rgrover1 | 260:ea7f9f14cc15 | 843 | } |
| rgrover1 | 260:ea7f9f14cc15 | 844 | } |
| rgrover1 | 260:ea7f9f14cc15 | 845 | |
| rgrover1 | 260:ea7f9f14cc15 | 846 | void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { |
| rgrover1 | 260:ea7f9f14cc15 | 847 | state.connected = 0; |
| rgrover1 | 260:ea7f9f14cc15 | 848 | if (onDisconnection) { |
| rgrover1 | 260:ea7f9f14cc15 | 849 | onDisconnection(handle, reason); |
| rgrover1 | 260:ea7f9f14cc15 | 850 | } |
| rgrover1 | 260:ea7f9f14cc15 | 851 | disconnectionCallChain.call(); |
| rgrover1 | 260:ea7f9f14cc15 | 852 | } |
| rgrover1 | 260:ea7f9f14cc15 | 853 | |
| rgrover1 | 363:a3d59a6e5da0 | 854 | void processSecuritySetupInitiatedEvent(Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { |
| rgrover1 | 364:03a7a439a3bf | 855 | if (onSecuritySetupInitiated) { |
| rgrover1 | 364:03a7a439a3bf | 856 | onSecuritySetupInitiated(handle, allowBonding, requireMITM, iocaps); |
| rgrover1 | 349:b8b2b3973c47 | 857 | } |
| rgrover1 | 349:b8b2b3973c47 | 858 | } |
| rgrover1 | 349:b8b2b3973c47 | 859 | |
| rgrover1 | 363:a3d59a6e5da0 | 860 | void processSecuritySetupCompletedEvent(Handle_t handle, SecurityCompletionStatus_t status) { |
| rgrover1 | 364:03a7a439a3bf | 861 | if (onSecuritySetupCompleted) { |
| rgrover1 | 364:03a7a439a3bf | 862 | onSecuritySetupCompleted(handle, status); |
| rgrover1 | 349:b8b2b3973c47 | 863 | } |
| rgrover1 | 349:b8b2b3973c47 | 864 | } |
| rgrover1 | 349:b8b2b3973c47 | 865 | |
| rgrover1 | 362:3b1ff00ad8a4 | 866 | void processLinkSecuredEvent(Handle_t handle, SecurityMode_t securityMode) { |
| rgrover1 | 349:b8b2b3973c47 | 867 | if (onLinkSecured) { |
| rgrover1 | 362:3b1ff00ad8a4 | 868 | onLinkSecured(handle, securityMode); |
| rgrover1 | 349:b8b2b3973c47 | 869 | } |
| rgrover1 | 349:b8b2b3973c47 | 870 | } |
| rgrover1 | 349:b8b2b3973c47 | 871 | |
| rgrover1 | 349:b8b2b3973c47 | 872 | void processSecurityContextStoredEvent(Handle_t handle) { |
| rgrover1 | 349:b8b2b3973c47 | 873 | if (onSecurityContextStored) { |
| rgrover1 | 349:b8b2b3973c47 | 874 | onSecurityContextStored(handle); |
| rgrover1 | 349:b8b2b3973c47 | 875 | } |
| rgrover1 | 349:b8b2b3973c47 | 876 | } |
| rgrover1 | 349:b8b2b3973c47 | 877 | |
| rgrover1 | 369:9a76cc068644 | 878 | void processPasskeyDisplayEvent(Handle_t handle, const Passkey_t passkey) { |
| rgrover1 | 369:9a76cc068644 | 879 | if (onPasskeyDisplay) { |
| rgrover1 | 369:9a76cc068644 | 880 | onPasskeyDisplay(handle, passkey); |
| rgrover1 | 369:9a76cc068644 | 881 | } |
| rgrover1 | 369:9a76cc068644 | 882 | } |
| rgrover1 | 369:9a76cc068644 | 883 | |
| rgrover1 | 537:00d5affbb2b2 | 884 | void processAdvertisementReport(const Address_t peerAddr, |
| rgrover1 | 537:00d5affbb2b2 | 885 | int8_t rssi, |
| rgrover1 | 537:00d5affbb2b2 | 886 | bool isScanResponse, |
| rgrover1 | 537:00d5affbb2b2 | 887 | GapAdvertisingParams::AdvertisingType_t type, |
| rgrover1 | 537:00d5affbb2b2 | 888 | uint8_t advertisingDataLen, |
| rgrover1 | 537:00d5affbb2b2 | 889 | const uint8_t *advertisingData) { |
| rgrover1 | 406:cec6778acc66 | 890 | AdvertisementCallbackParams_t params; |
| rgrover1 | 406:cec6778acc66 | 891 | memcpy(params.peerAddr, peerAddr, ADDR_LEN); |
| rgrover1 | 406:cec6778acc66 | 892 | params.rssi = rssi; |
| rgrover1 | 406:cec6778acc66 | 893 | params.isScanResponse = isScanResponse; |
| rgrover1 | 406:cec6778acc66 | 894 | params.type = type; |
| rgrover1 | 406:cec6778acc66 | 895 | params.advertisingDataLen = advertisingDataLen; |
| rgrover1 | 406:cec6778acc66 | 896 | params.advertisingData = advertisingData; |
| rgrover1 | 406:cec6778acc66 | 897 | onAdvertisementReport.call(¶ms); |
| rgrover1 | 382:dcd0428dadb0 | 898 | } |
| rgrover1 | 382:dcd0428dadb0 | 899 | |
| rgrover1 | 260:ea7f9f14cc15 | 900 | void processEvent(GapEvents::gapEvent_e type) { |
| rgrover1 | 260:ea7f9f14cc15 | 901 | switch (type) { |
| rgrover1 | 260:ea7f9f14cc15 | 902 | case GapEvents::GAP_EVENT_TIMEOUT: |
| rgrover1 | 260:ea7f9f14cc15 | 903 | state.advertising = 0; |
| rgrover1 | 260:ea7f9f14cc15 | 904 | if (onTimeout) { |
| rgrover1 | 260:ea7f9f14cc15 | 905 | onTimeout(); |
| rgrover1 | 260:ea7f9f14cc15 | 906 | } |
| rgrover1 | 260:ea7f9f14cc15 | 907 | break; |
| rgrover1 | 267:ad6f6f40eb24 | 908 | default: |
| rgrover1 | 267:ad6f6f40eb24 | 909 | break; |
| rgrover1 | 260:ea7f9f14cc15 | 910 | } |
| rgrover1 | 260:ea7f9f14cc15 | 911 | } |
| rgrover1 | 260:ea7f9f14cc15 | 912 | |
| rgrover1 | 260:ea7f9f14cc15 | 913 | protected: |
| rgrover1 | 532:a709cfc1500d | 914 | GapAdvertisingParams _advParams; |
| rgrover1 | 532:a709cfc1500d | 915 | GapAdvertisingData _advPayload; |
| rgrover1 | 532:a709cfc1500d | 916 | GapScanningParams _scanningParams; |
| rgrover1 | 532:a709cfc1500d | 917 | GapAdvertisingData _scanResponse; |
| rgrover1 | 531:bdcd44b03974 | 918 | |
| rgrover1 | 363:a3d59a6e5da0 | 919 | GapState_t state; |
| rgrover1 | 260:ea7f9f14cc15 | 920 | |
| rgrover1 | 337:e7c2eb38f5cc | 921 | protected: |
| rgrover1 | 363:a3d59a6e5da0 | 922 | EventCallback_t onTimeout; |
| rgrover1 | 363:a3d59a6e5da0 | 923 | ConnectionEventCallback_t onConnection; |
| rgrover1 | 363:a3d59a6e5da0 | 924 | DisconnectionEventCallback_t onDisconnection; |
| rgrover1 | 363:a3d59a6e5da0 | 925 | RadioNotificationEventCallback_t onRadioNotification; |
| rgrover1 | 364:03a7a439a3bf | 926 | SecuritySetupInitiatedCallback_t onSecuritySetupInitiated; |
| rgrover1 | 364:03a7a439a3bf | 927 | SecuritySetupCompletedCallback_t onSecuritySetupCompleted; |
| rgrover1 | 363:a3d59a6e5da0 | 928 | LinkSecuredCallback_t onLinkSecured; |
| rgrover1 | 363:a3d59a6e5da0 | 929 | HandleSpecificEvent_t onSecurityContextStored; |
| rgrover1 | 369:9a76cc068644 | 930 | PasskeyDisplayCallback_t onPasskeyDisplay; |
| rgrover1 | 385:6e66d1c6de00 | 931 | AdvertisementReportCallback_t onAdvertisementReport; |
| rgrover1 | 363:a3d59a6e5da0 | 932 | CallChain disconnectionCallChain; |
| rgrover1 | 260:ea7f9f14cc15 | 933 | |
| rgrover1 | 260:ea7f9f14cc15 | 934 | private: |
| rgrover1 | 260:ea7f9f14cc15 | 935 | /* disallow copy and assignment */ |
| rgrover1 | 260:ea7f9f14cc15 | 936 | Gap(const Gap &); |
| rgrover1 | 260:ea7f9f14cc15 | 937 | Gap& operator=(const Gap &); |
| rgrover1 | 260:ea7f9f14cc15 | 938 | }; |
| rgrover1 | 260:ea7f9f14cc15 | 939 | |
| rgrover1 | 260:ea7f9f14cc15 | 940 | #endif // ifndef __GAP_H__ |
