High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Thu Jul 02 09:06:11 2015 +0100
Revision:
716:11b41f651697
Child:
734:4872b70437ce
Synchronized with git rev d80fec88
Author: Rohit Grover
Release 0.4.0
=============

This is a major release which introduces the GATT Client functionality. It
also aligns BLE_API with builds using our new package manager: yotta
(https://github.com/armmbed/yotta).

Many APIs have seen some redesign. We encourage our users to pay attention to
the changes and migrate appropriately over time. We've also taken care to
ensure that existing code continues to work the same way. There's more
documentation in the form of comment headers for APIs to explain proper usage;
in many cases comment headers suggest alternative use of APIs.

Enhancements
~~~~~~~~~~~~

* Introduce GattClient. This includes functionality for service-discovery,
connections, and attribute-reads and writes. You'll find a demo program for
LEDBlinker on the mbed.org Bluetooth team page to use the new APIs. Some of
the GATT client functionality hasn't been implemented yet, but the APIs have
been added.

* Most APIs in the abstract base classes like Gap and GattServer return
BLE_ERROR_NOT_IMPLEMENTED. Previously many APIs were pure-virtual, which did
not permit partial ports to compile.

* We've added a new abstract base class for SecurityManager. All security
related APIs have been moved into that.

* BLEDevice has been renamed as BLE. A deprecated alias for BLEDevice is
available to support existing code.

* There has been a major cleanup of APIs under BLE. APIs have now been
categorized as belonging to Gap, GattServer, GattClient, or SecurityManager.
There are accessors to get references for Gap, GattServer, GattClient, and
SecurityManager. A former call to ble.setAddress(...) is now expected to be
achieved with ble.gap().setAddress(...).

* We've cleaned up our APIs, and this has resulted in dropping some APIs like
BLE::reset().

* We've also dropped GattServer::initializeGattDatabase(). THis was added at
some point to support controllers where a commit point was needed to
indicate when the application had finished constructing the GATT database.
This API would get called internally before Gap::startAdvertising(). We now
expect the underlying port to do the equivalent of initializeGattDatabase()
implicitly upon Gap::startAdvertising().

* The callback for BLE.onTimeout() now receives a TimeoutSource_t to indicate
the cause of the timeout. This is perhaps the only breaking API change. We
expect it to have very little disruptive effect.

* We've added a version of Gap::disconnect() which takes a connection handle.
The previous API (which did not take a connection handle) has been
deprecated; it will still work for situations where there's only a single
active connection. We hold on to that API to allow existing code to migrate
to the new API.

Bugfixes
~~~~~~~~

* None.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 716:11b41f651697 1 /* mbed Microcontroller Library
rgrover1 716:11b41f651697 2 * Copyright (c) 2006-2015 ARM Limited
rgrover1 716:11b41f651697 3 *
rgrover1 716:11b41f651697 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 716:11b41f651697 5 * you may not use this file except in compliance with the License.
rgrover1 716:11b41f651697 6 * You may obtain a copy of the License at
rgrover1 716:11b41f651697 7 *
rgrover1 716:11b41f651697 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 716:11b41f651697 9 *
rgrover1 716:11b41f651697 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 716:11b41f651697 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 716:11b41f651697 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 716:11b41f651697 13 * See the License for the specific language governing permissions and
rgrover1 716:11b41f651697 14 * limitations under the License.
rgrover1 716:11b41f651697 15 */
rgrover1 716:11b41f651697 16
rgrover1 716:11b41f651697 17 #ifndef __SECURITY_MANAGER_H__
rgrover1 716:11b41f651697 18 #define __SECURITY_MANAGER_H__
rgrover1 716:11b41f651697 19
rgrover1 716:11b41f651697 20 #include <stdint.h>
rgrover1 716:11b41f651697 21
rgrover1 716:11b41f651697 22 #include "Gap.h"
rgrover1 716:11b41f651697 23
rgrover1 716:11b41f651697 24 class SecurityManager {
rgrover1 716:11b41f651697 25 public:
rgrover1 716:11b41f651697 26 enum SecurityMode_t {
rgrover1 716:11b41f651697 27 SECURITY_MODE_NO_ACCESS,
rgrover1 716:11b41f651697 28 SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */
rgrover1 716:11b41f651697 29 SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */
rgrover1 716:11b41f651697 30 SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */
rgrover1 716:11b41f651697 31 SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */
rgrover1 716:11b41f651697 32 SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */
rgrover1 716:11b41f651697 33 };
rgrover1 716:11b41f651697 34
rgrover1 716:11b41f651697 35 /**
rgrover1 716:11b41f651697 36 * @brief Defines possible security status/states.
rgrover1 716:11b41f651697 37 *
rgrover1 716:11b41f651697 38 * @details Defines possible security status/states of a link when requested by getLinkSecurity().
rgrover1 716:11b41f651697 39 */
rgrover1 716:11b41f651697 40 enum LinkSecurityStatus_t {
rgrover1 716:11b41f651697 41 NOT_ENCRYPTED, /**< The link is not secured. */
rgrover1 716:11b41f651697 42 ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/
rgrover1 716:11b41f651697 43 ENCRYPTED /**< The link is secure.*/
rgrover1 716:11b41f651697 44 };
rgrover1 716:11b41f651697 45
rgrover1 716:11b41f651697 46 enum SecurityIOCapabilities_t {
rgrover1 716:11b41f651697 47 IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */
rgrover1 716:11b41f651697 48 IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */
rgrover1 716:11b41f651697 49 IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */
rgrover1 716:11b41f651697 50 IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */
rgrover1 716:11b41f651697 51 IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */
rgrover1 716:11b41f651697 52 };
rgrover1 716:11b41f651697 53
rgrover1 716:11b41f651697 54 enum SecurityCompletionStatus_t {
rgrover1 716:11b41f651697 55 SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */
rgrover1 716:11b41f651697 56 SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */
rgrover1 716:11b41f651697 57 SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */
rgrover1 716:11b41f651697 58 SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */
rgrover1 716:11b41f651697 59 SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */
rgrover1 716:11b41f651697 60 SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */
rgrover1 716:11b41f651697 61 SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */
rgrover1 716:11b41f651697 62 SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */
rgrover1 716:11b41f651697 63 SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */
rgrover1 716:11b41f651697 64 SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */
rgrover1 716:11b41f651697 65 SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */
rgrover1 716:11b41f651697 66 SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */
rgrover1 716:11b41f651697 67 SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */
rgrover1 716:11b41f651697 68 };
rgrover1 716:11b41f651697 69
rgrover1 716:11b41f651697 70 /**
rgrover1 716:11b41f651697 71 * Declaration of type containing a passkey to be used during pairing. This
rgrover1 716:11b41f651697 72 * is passed into initializeSecurity() to specify a pre-programmed passkey
rgrover1 716:11b41f651697 73 * for authentication instead of generating a random one.
rgrover1 716:11b41f651697 74 */
rgrover1 716:11b41f651697 75 static const unsigned PASSKEY_LEN = 6;
rgrover1 716:11b41f651697 76 typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
rgrover1 716:11b41f651697 77
rgrover1 716:11b41f651697 78 public:
rgrover1 716:11b41f651697 79 typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle);
rgrover1 716:11b41f651697 80 typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps);
rgrover1 716:11b41f651697 81 typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status);
rgrover1 716:11b41f651697 82 typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode);
rgrover1 716:11b41f651697 83 typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey);
rgrover1 716:11b41f651697 84
rgrover1 716:11b41f651697 85 /*
rgrover1 716:11b41f651697 86 * The following functions are meant to be overridden in the platform-specific sub-class.
rgrover1 716:11b41f651697 87 */
rgrover1 716:11b41f651697 88 public:
rgrover1 716:11b41f651697 89 /**
rgrover1 716:11b41f651697 90 * Enable the BLE stack's Security Manager. The Security Manager implements
rgrover1 716:11b41f651697 91 * the actual cryptographic algorithms and protocol exchanges that allow two
rgrover1 716:11b41f651697 92 * devices to securely exchange data and privately detect each other.
rgrover1 716:11b41f651697 93 * Calling this API is a prerequisite for encryption and pairing (bonding).
rgrover1 716:11b41f651697 94 *
rgrover1 716:11b41f651697 95 * @param[in] enableBonding Allow for bonding.
rgrover1 716:11b41f651697 96 * @param[in] requireMITM Require protection for man-in-the-middle attacks.
rgrover1 716:11b41f651697 97 * @param[in] iocaps To specify IO capabilities of this peripheral,
rgrover1 716:11b41f651697 98 * such as availability of a display or keyboard to
rgrover1 716:11b41f651697 99 * support out-of-band exchanges of security data.
rgrover1 716:11b41f651697 100 * @param[in] passkey To specify a static passkey.
rgrover1 716:11b41f651697 101 *
rgrover1 716:11b41f651697 102 * @return BLE_ERROR_NONE on success.
rgrover1 716:11b41f651697 103 */
rgrover1 716:11b41f651697 104 virtual ble_error_t init(bool enableBonding = true,
rgrover1 716:11b41f651697 105 bool requireMITM = true,
rgrover1 716:11b41f651697 106 SecurityIOCapabilities_t iocaps = IO_CAPS_NONE,
rgrover1 716:11b41f651697 107 const Passkey_t passkey = NULL) {
rgrover1 716:11b41f651697 108 return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */
rgrover1 716:11b41f651697 109 }
rgrover1 716:11b41f651697 110
rgrover1 716:11b41f651697 111 /**
rgrover1 716:11b41f651697 112 * Get the security status of a connection.
rgrover1 716:11b41f651697 113 *
rgrover1 716:11b41f651697 114 * @param[in] connectionHandle Handle to identify the connection.
rgrover1 716:11b41f651697 115 * @param[out] securityStatusP security status.
rgrover1 716:11b41f651697 116 *
rgrover1 716:11b41f651697 117 * @return BLE_SUCCESS Or appropriate error code indicating reason for failure.
rgrover1 716:11b41f651697 118 */
rgrover1 716:11b41f651697 119 virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) {
rgrover1 716:11b41f651697 120 return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */
rgrover1 716:11b41f651697 121 }
rgrover1 716:11b41f651697 122
rgrover1 716:11b41f651697 123 /**
rgrover1 716:11b41f651697 124 * Delete all peer device context and all related bonding information from
rgrover1 716:11b41f651697 125 * the database within the security manager.
rgrover1 716:11b41f651697 126 *
rgrover1 716:11b41f651697 127 * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure.
rgrover1 716:11b41f651697 128 * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or
rgrover1 716:11b41f651697 129 * application registration.
rgrover1 716:11b41f651697 130 */
rgrover1 716:11b41f651697 131 virtual ble_error_t purgeAllBondingState(void) {
rgrover1 716:11b41f651697 132 return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */
rgrover1 716:11b41f651697 133 }
rgrover1 716:11b41f651697 134
rgrover1 716:11b41f651697 135 /* Event callback handlers. */
rgrover1 716:11b41f651697 136 public:
rgrover1 716:11b41f651697 137 /**
rgrover1 716:11b41f651697 138 * To indicate that security procedure for link has started.
rgrover1 716:11b41f651697 139 */
rgrover1 716:11b41f651697 140 virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;}
rgrover1 716:11b41f651697 141
rgrover1 716:11b41f651697 142 /**
rgrover1 716:11b41f651697 143 * To indicate that security procedure for link has completed.
rgrover1 716:11b41f651697 144 */
rgrover1 716:11b41f651697 145 virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;}
rgrover1 716:11b41f651697 146
rgrover1 716:11b41f651697 147 /**
rgrover1 716:11b41f651697 148 * To indicate that link with the peer is secured. For bonded devices,
rgrover1 716:11b41f651697 149 * subsequent re-connections with bonded peer will result only in this callback
rgrover1 716:11b41f651697 150 * when the link is secured and setup procedures will not occur unless the
rgrover1 716:11b41f651697 151 * bonding information is either lost or deleted on either or both sides.
rgrover1 716:11b41f651697 152 */
rgrover1 716:11b41f651697 153 virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;}
rgrover1 716:11b41f651697 154
rgrover1 716:11b41f651697 155 /**
rgrover1 716:11b41f651697 156 * To indicate that device context is stored persistently.
rgrover1 716:11b41f651697 157 */
rgrover1 716:11b41f651697 158 virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;}
rgrover1 716:11b41f651697 159
rgrover1 716:11b41f651697 160 /**
rgrover1 716:11b41f651697 161 * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability.
rgrover1 716:11b41f651697 162 */
rgrover1 716:11b41f651697 163 virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;}
rgrover1 716:11b41f651697 164
rgrover1 716:11b41f651697 165 /* Entry points for the underlying stack to report events back to the user. */
rgrover1 716:11b41f651697 166 public:
rgrover1 716:11b41f651697 167 void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) {
rgrover1 716:11b41f651697 168 if (securitySetupInitiatedCallback) {
rgrover1 716:11b41f651697 169 securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps);
rgrover1 716:11b41f651697 170 }
rgrover1 716:11b41f651697 171 }
rgrover1 716:11b41f651697 172
rgrover1 716:11b41f651697 173 void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) {
rgrover1 716:11b41f651697 174 if (securitySetupCompletedCallback) {
rgrover1 716:11b41f651697 175 securitySetupCompletedCallback(handle, status);
rgrover1 716:11b41f651697 176 }
rgrover1 716:11b41f651697 177 }
rgrover1 716:11b41f651697 178
rgrover1 716:11b41f651697 179 void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) {
rgrover1 716:11b41f651697 180 if (linkSecuredCallback) {
rgrover1 716:11b41f651697 181 linkSecuredCallback(handle, securityMode);
rgrover1 716:11b41f651697 182 }
rgrover1 716:11b41f651697 183 }
rgrover1 716:11b41f651697 184
rgrover1 716:11b41f651697 185 void processSecurityContextStoredEvent(Gap::Handle_t handle) {
rgrover1 716:11b41f651697 186 if (securityContextStoredCallback) {
rgrover1 716:11b41f651697 187 securityContextStoredCallback(handle);
rgrover1 716:11b41f651697 188 }
rgrover1 716:11b41f651697 189 }
rgrover1 716:11b41f651697 190
rgrover1 716:11b41f651697 191 void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) {
rgrover1 716:11b41f651697 192 if (passkeyDisplayCallback) {
rgrover1 716:11b41f651697 193 passkeyDisplayCallback(handle, passkey);
rgrover1 716:11b41f651697 194 }
rgrover1 716:11b41f651697 195 }
rgrover1 716:11b41f651697 196
rgrover1 716:11b41f651697 197 protected:
rgrover1 716:11b41f651697 198 SecurityManager() :
rgrover1 716:11b41f651697 199 securitySetupInitiatedCallback(),
rgrover1 716:11b41f651697 200 securitySetupCompletedCallback(),
rgrover1 716:11b41f651697 201 linkSecuredCallback(),
rgrover1 716:11b41f651697 202 securityContextStoredCallback(),
rgrover1 716:11b41f651697 203 passkeyDisplayCallback() {
rgrover1 716:11b41f651697 204 /* empty */
rgrover1 716:11b41f651697 205 }
rgrover1 716:11b41f651697 206
rgrover1 716:11b41f651697 207 protected:
rgrover1 716:11b41f651697 208 SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback;
rgrover1 716:11b41f651697 209 SecuritySetupCompletedCallback_t securitySetupCompletedCallback;
rgrover1 716:11b41f651697 210 LinkSecuredCallback_t linkSecuredCallback;
rgrover1 716:11b41f651697 211 HandleSpecificEvent_t securityContextStoredCallback;
rgrover1 716:11b41f651697 212 PasskeyDisplayCallback_t passkeyDisplayCallback;
rgrover1 716:11b41f651697 213 };
rgrover1 716:11b41f651697 214
rgrover1 716:11b41f651697 215 #endif /*__SECURITY_MANAGER_H__*/