Merge pull request #5295 from pan-/GAP-platform-abstraction-layer

BLE: Gap platform abstraction layer
pull/5471/head
Martin Kojtal 2017-11-09 16:54:11 +00:00 committed by GitHub
commit 82f5b58f4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1904 additions and 0 deletions

View File

@ -0,0 +1,155 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_SAFE_ENUM_H_
#define BLE_SAFE_ENUM_H_
#include <stddef.h>
#include <stdint.h>
namespace ble {
/**
* Helper class used to define safe enumerations.
*
* C++ 98 enums expose different security holes:
* - Scope The scope of the enum is the scope defining it. In other words,
* enumerator defined at namespace scope are in the same scope that other
* enumerator defined in that namespace even if they belong to a different
* enumeration.
* As a result it is really easy to collide names between two different
* enumerators. At the end, the programmer has to protect its declaration
* with long prefixing.
* - Unsafe comparison: enumerators really just are named integer and can be
* implicitly converted to integer. As a result it is possible to compare
* value of different enum type.
* - Layout: The layout type of enumerations is implementation defined.
*
* This template class expose a framework to overcome those issues:
*
* First enum has to be defined in a structure which inherit from this class.
* The target type is the name of the structure containing the enumeration
* while LayoutType is the inner type used to stored the enum.
*
* Comparison operator are provided so it is not possible to compare a SafeEnum
* of a type to another SafeEnum of a different type.
*
* Implicit conversion to integer is not defined, users have to either use the
* value function which return the integer value stored in an EnumType. Client
* class can also define their own conversion operation.
*
* @tparam Target structure containing the enumeration definition.
* @tparam LayoutType Inner type used to store enumeration value.
*
* @code
struct color_t : SafeEnum<color_t> {
enum type {
RED,
GREEN,
BLACK
};
color_t(type) : SafeEnum<color_t>(type) { }
};
// use an uint8_t to store the enumeration value
struct shape_t : SafeEnum<shape_t, uint8_t> {
enum type {
RECTANGLE,
CIRCLE,
TRIANGLE
};
shape_t(type) : SafeEnum<shape_t>(type) { }
};
// shape enumerator is in the shape_t scope.
shape_t shape = shape_t::RECTANGLE;
shape_t shape = color_t::RED; // Compilation error
if (shape == shape_t::CIRCLE) {
}
// compilation error
if (shape == color_t::RED) {
}
void sink(shape_t); (1)
void sink(color_t); (2)
sink(shape); // use overload (1)
sink(color); // use overload (2)
// explicit access to the value is mandatory when a SafeEnum value is used
// as the condition in a switch statement
switch(shape.value()) {
case shape_t::RECTANGLE:
break;
}
* @endcode
*/
template<typename Target, typename LayoutType = unsigned int>
struct SafeEnum {
/**
* Construction of an enumeration value.
*/
SafeEnum(LayoutType value) : _value(value) { }
/**
* Equal to operator for SafeEnum instances.
*
* @param lhs left hand side of the comparison
* @param rhs right hand side of the comparison
*
* @return true if the inner value of lhs and rhs are equal and false
* otherwise.
*/
friend bool operator==(SafeEnum lhs, SafeEnum rhs) {
return lhs._value == rhs._value;
}
/**
* Not equal to operator for SafeEnum instances.
*
* @param lhs left hand side of the comparison
* @param rhs right hand side of the comparison
*
* @return true if the inner value of lhs and rhs are not equal and false
* otherwise.
*/
friend bool operator!=(SafeEnum lhs, SafeEnum rhs) {
return !(lhs == rhs);
}
/**
* Explicit access to the inner value of the SafeEnum instance.
*/
LayoutType value() const {
return _value;
}
private:
LayoutType _value;
};
} // namespace ble
#endif /* BLE_SAFE_ENUM_H_ */

View File

@ -0,0 +1,443 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_PAL_GAP_MESSAGE_H_
#define BLE_PAL_GAP_MESSAGE_H_
#include "GapTypes.h"
#include "ble/ArrayView.h"
namespace ble {
namespace pal {
/**
* Enumeration of GAP event types
*/
struct GapEventType : SafeEnum<GapEventType, uint8_t> {
enum type {
/**
* Event type used by GapUnexpectedErrorEvent
*/
UNEXPECTED_ERROR,
/**
* Event type used by GapConnectionCompleteEvent
*/
CONNECTION_COMPLETE,
/**
* Event type used by GapAdvertisingReportEvent
*/
ADVERTISING_REPORT,
/**
* Event type used by GapConnectionUpdateEvent
* */
CONNECTION_UPDATE,
/**
* Event type used by GapRemoteConnectionParameterRequestEvent
*/
REMOTE_CONNECTION_PARAMETER_REQUEST,
/**
* Event type used by GapDisconnectionCompleteEvent
*/
DISCONNECTION_COMPLETE
};
GapEventType(type event_type) : SafeEnum<GapEventType, uint8_t>(event_type) { }
};
/**
* Base class of a Gap Event.
*
* Client should use the field type to deduce the actual type of the event.
*/
struct GapEvent {
const GapEventType type;
protected:
GapEvent(GapEventType type) : type(type) { }
// Disable copy construction and copy assignement operations.
GapEvent(const GapEvent&);
GapEvent& operator=(const GapEvent&);
};
/**
* Model an unexpected error that happen during a gap procedure.
*
* This class is mainly used to notify user code of an unexpected error returned
* in an HCI command complete event.
*/
struct GapUnexpectedErrorEvent : public GapEvent {
GapUnexpectedErrorEvent(uint16_t opcode, uint8_t error_code) :
GapEvent(GapEventType::UNEXPECTED_ERROR),
opcode(opcode), error_code(error_code) { }
/**
* Opcode composed of the OCF and OGF of the command which has returned an
* error.
*/
const uint16_t opcode;
/**
* Error code
*/
const uint8_t error_code;
};
/**
* Indicate to both ends (slave or master) the end of the connection process.
*
* This structure should be used for Connection Complete Events and Enhanced
* Connection Complete Event.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.65.1 LE Connection Complete Event
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.65.10 LE Enhanced Connection
*/
struct GapConnectionCompleteEvent : public GapEvent {
/**
* Construct a new GapConnectionCompleteEvent.
*
* @param status Status of the operation: 0x00 in case of success otherwise
* the error code associated with the failure.
*
* @param connection_handle handle of the connection created. This handle
* will be used to address the connection in any connection oriented
* operation.
*
* @param role Role of the LE subsystem in the connection.
*
* @param address_type Type of address used by the peer for this connection.
*
* @param address Address of the peer used to establish the connection.
*
* @param connection_interval Connection interval used on this connection.
* It shall be in a range [0x0006 : 0x0C80]. A unit is equal to 1.25ms.
*
* @param connection_latency Number of connection events the slave can
* drop.
*
* @param supervision_timeout Supervision timeout of the connection. It
* shall be in the range [0x000A : 0x0C80] where a unit represent 10ms.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.65.1 LE Connection Complete Event
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.65.10 LE Enhanced Connection
* Complete Event
*/
GapConnectionCompleteEvent(
uint8_t status,
connection_handle_t connection_handle,
connection_role_t role,
advertising_peer_address_type_t peer_address_type,
const address_t& peer_address,
uint16_t connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout
) :
GapEvent(GapEventType::CONNECTION_COMPLETE),
status(status),
connection_handle(connection_handle),
role(role),
peer_address_type(peer_address_type),
peer_address(peer_address),
connection_interval(connection_interval),
connection_latency(connection_latency),
supervision_timeout(supervision_timeout) {
}
/*
* @param status Indicate if the connection succesfully completed or not:
* - 0: Connection successfuly completed
* - [0x01 : 0xFF] Connection failed to complete, the value represent
* the code for the error.
*/
const uint8_t status;
/**
* Handle of the connection created, valid if status is equal to 0.
* @important Valid if status is equal to 0.
*/
const connection_handle_t connection_handle;
/**
* Role of the device in the connection
* @important Valid if status is equal to 0.
*/
const connection_role_t role;
/**
* Peer address type.
*/
const advertising_peer_address_type_t peer_address_type;
/**
* Peer address.
*/
const address_t peer_address;
/**
* Connection interval used in this connection.
* It shall be in a range [0x0006 : 0x0C80]. A unit is equal to 1.25ms.
*/
const uint16_t connection_interval;
/**
* Number of connection events the slave can drop.
*/
const uint16_t connection_latency;
/**
* Supervision timeout of the connection
* It shall be in the range [0x000A : 0x0C80] where a unit represent 10ms.
*/
const uint16_t supervision_timeout;
};
/**
* Report advertising from one or more LE device.
*
* @important This class has to be implemented by the BLE port.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.65.2 LE Advertising Report Event
*/
struct GapAdvertisingReportEvent : public GapEvent {
/**
* POD representing an advertising captured by the LE subsystem.
*/
struct advertising_t {
received_advertising_type_t type;
connection_peer_address_type_t address_type;
const address_t& address;
ArrayView<const uint8_t> data;
int8_t rssi;
};
GapAdvertisingReportEvent() : GapEvent(GapEventType::ADVERTISING_REPORT) { }
virtual ~GapAdvertisingReportEvent() { }
/**
* Count of advertising in this event.
*/
virtual uint8_t size() const = 0;
/**
* Access the advertising at index i.
*/
virtual advertising_t operator[](uint8_t i) const = 0;
};
/**
* Indicates the connection update process completion.
*
* If no parameters are updated after a connection update request from the peer
* then this event shall not be emmited.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.65.3 LE Connection Update Complete
* Event.
*/
struct GapConnectionUpdateEvent : public GapEvent {
/**
* Construct a connection update event for a successful process.
*
* @param status Status of the connection update event operation. If equal
* to 0x00 then the process was successful, otherwise the status indicates
* the reason of the faillure.
*
* @param connection_handle Handle of the connection updated.
*
* @param connection_interval New connection interval used by the connection.
*
* @param Connection_latency New connection latency used by the connection.
*
* @param supervision_timeout New connection supervision timeout.
*/
GapConnectionUpdateEvent(
uint8_t status,
connection_handle_t connection_handle,
uint16_t connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout
) :
GapEvent(GapEventType::CONNECTION_UPDATE),
status(status),
connection_handle(connection_handle),
connection_interval(connection_interval),
connection_latency(connection_latency),
supervision_timeout(supervision_timeout) {
}
/**
* If equal to 0, the connection update has succesfully completed otherwise
* the process has failled and this field represent the error associated to
* the faillure.
*/
const uint8_t status;
/**
* Handle of the connection which has completed the connection update
* process.
*/
const connection_handle_t connection_handle;
/**
* New connection interval used by the connection.
* It shall be in a range [0x0006 : 0x0C80]. A unit is equal to 1.25ms.
*/
const uint16_t connection_interval;
/*
* New number of connection events the slave can drop.
*/
const uint16_t connection_latency;
/*
* New supervision timeout of the connection.
* It shall be in the range [0x000A : 0x0C80] where a unit represent 10ms.
*/
const uint16_t supervision_timeout;
};
/**
* indicate a request from the peer to change the connection parameters.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.65.6 LE Remote Connection Parameter
* Request Event.
*/
struct GapRemoteConnectionParameterRequestEvent : public GapEvent {
/**
* Construct a new remote connection parameter request event.
*
* @param connection_handle Handle of the connection with the peer
* requesting the parameter update
*
* @param min_connection_interval Minimum value of the connection interval
* requested by the peer.
*
* @param max_connection_interval Maximum value of the connection interval
* requested by the peer.
*
* @param connection_latency Slave latency requested by the peer.
*
* @param supervision_timeout Supervision timeout requested by the peer.
*/
GapRemoteConnectionParameterRequestEvent(
connection_handle_t connection_handle,
uint16_t min_connection_interval,
uint16_t max_connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout
) : GapEvent(GapEventType::REMOTE_CONNECTION_PARAMETER_REQUEST),
connection_handle(connection_handle),
min_connection_interval(min_connection_interval),
max_connection_interval(max_connection_interval),
connection_latency(connection_latency),
supervision_timeout(supervision_timeout) {
}
/**
* Handle of the connection with the peer requesting the parameter update.
*/
const connection_handle_t connection_handle;
/**
* Minimum value of the connection interval requested by the peer.
* It shall be in a range [0x0006 : 0x0C80]. A unit is equal to 1.25ms.
*/
const uint16_t min_connection_interval;
/**
* Maximum value of the connection interval requested by the peer.
* It shall be in a range [0x0006 : 0x0C80]. A unit is equal to 1.25ms.
*/
const uint16_t max_connection_interval;
/*
* Slave latency requested by the peer.
*/
const uint16_t connection_latency;
/*
* Supervision timeout requested by the peer.
* It shall be in the range [0x000A : 0x0C80] where a unit represent 10ms.
*/
const uint16_t supervision_timeout;
};
/**
* Indicate the end of a disconnection process.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.7.5 Disconnection Complete Event.
*/
struct GapDisconnectionCompleteEvent : public GapEvent {
/**
* Construct a disconnection complete event.
*
* @param status Status of the procedure. If equal to 0 then the
* disconnection process complete successfully. Otherwise it represents the
* error code associated with the faillure.
*
* @param connection_handle Handle of the connection disconnected.
*
* @param reason Reason of the disconnection
*/
GapDisconnectionCompleteEvent(
uint8_t status,
connection_handle_t connection_handle,
uint8_t reason
) : GapEvent(GapEventType::DISCONNECTION_COMPLETE),
status(status),
connection_handle(connection_handle),
reason(reason) {
}
/**
* Status of the procedure. If equal to 0 then the procedure was a success
* otherwise this variable contains the error code associated with the
* faillure.
*/
const uint8_t status;
/**
* Handle of the connection used for the procedure.
*/
const connection_handle_t connection_handle;
/**
* Reason for disconnection.
*
* @important ignored in case of faillure.
*/
const uint8_t reason;
};
} // namespace pal
} // namespace ble
#endif /* BLE_PAL_GAP_MESSAGE_H_ */

View File

@ -0,0 +1,610 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_PAL_GAP_TYPES_H_
#define BLE_PAL_GAP_TYPES_H_
#include <algorithm>
#include "ble/BLETypes.h"
#include "ble/SafeEnum.h"
namespace ble {
namespace pal {
/**
* Type of advertising the LE subsystem can use when it advertise.
*/
struct advertising_type_t : SafeEnum<advertising_type_t, uint8_t> {
enum type {
/**
* Connectable and scannable undirected advertising .
*/
ADV_IND = 0x00,
/**
* Connectable high duty cycle directed advertising
*/
ADV_DIRECT_IND = 0x01,
/**
* Scannable undirected advertising
*/
ADV_SCAN_IND = 0x02,
/**
* Non connectable undirected advertising
*/
ADV_NONCONN_IND = 0x03,
/**
* Connectable low duty cycle directed advertising
*/
ADV_DIRECT_IND_LOW_DUTY_CYCLE = 0x04
};
/**
* Construct a new advertising_type_t value.
*/
advertising_type_t(type value) :
SafeEnum<advertising_type_t, uint8_t>(value) { }
};
/**
* Type used to model the own address used during the following GAP operations:
* advertising, scanning and initiating
*/
struct own_address_type_t : SafeEnum<own_address_type_t, uint8_t> {
enum type {
/**
* Use the public device address
*/
PUBLIC_ADDRESS = 0x00,
/**
* Use the random device address
*/
RANDOM_ADDRESS = 0x01,
/**
* Generated resolvable private address based on the local IRK from the
* resolving list. Use the public address if no entry match in the resolving
* list.
*/
RESOLVABLE_PRIVATE_ADDRESS_PUBLIC_FALLBACK = 0x02,
/**
* Generated resolvable private address based on the local IRK from the
* resolving list. Use the random address if no entry match in the resolving
* list.
*/
RESOLVABLE_PRIVATE_ADDRESS_RANDOM_FALLBACK = 0x03,
};
/**
* Construct a new instance of own_address_type_t.
*/
own_address_type_t(type value) :
SafeEnum<own_address_type_t, uint8_t>(value) { }
};
/**
* Type modeling the peer address type during direct advertising.
*/
struct advertising_peer_address_type_t :
SafeEnum<advertising_peer_address_type_t, uint8_t> {
enum type {
/**
* Public device address or identity address.
*/
PUBLIC_ADDRESS = 0x00,
/**
* Random device address or random (static) identity address.
*/
RANDOM_ADDRESS = 0x01
};
/**
* Construct a new instance of advertising_peer_address_type_t.
*/
advertising_peer_address_type_t(type value) :
SafeEnum<advertising_peer_address_type_t, uint8_t>(value) { }
};
/**
* Peer address type used during connection initiating.
*/
struct connection_peer_address_type_t :
SafeEnum<connection_peer_address_type_t, uint8_t> {
enum type {
/**
* Public device address
*/
PUBLIC_ADDRESS = 0x00,
/**
* Random device address
*/
RANDOM_ADDRESS = 0x01,
/**
* Public identity address.
* @note remove once privacy mode is supported.
*/
PUBLIC_IDENTITY_ADDRESS = 0x02,
/**
* Random (static) identity address.
* @note remove once privacy mode is supported.
*/
RANDOM_IDENTITY_ADDRESS = 0x03
};
/**
* Construct a new connection_peer_address_type_t instance.
*/
connection_peer_address_type_t(type value) :
SafeEnum<connection_peer_address_type_t, uint8_t>(value) { }
};
/**
* Address type used in whitelist operations
*/
struct whitelist_address_type_t : SafeEnum<whitelist_address_type_t, uint8_t> {
enum type {
PUBLIC_DEVICE_ADDRESS = 0x00,
RANDOM_DEVICE_ADDRESS = 0x01,
/* TODO: to be added with bluetooth 5 support:
ANONYMOUS_ADVERTISEMENT_DEVICE_ADRESS
*/
};
/**
* Construct a new whitelist_address_type_t instance.
*/
whitelist_address_type_t(type value) :
SafeEnum<whitelist_address_type_t, uint8_t>(value) { }
};
/**
* Channel map which can be used during advertising.
*/
struct advertising_channel_map_t : SafeEnum<advertising_channel_map_t, uint8_t> {
enum type {
ADVERTISING_CHANNEL_37 = (1 << 0),
ADVERTISING_CHANNEL_38 = (1 << 1),
ADVERTISING_CHANNEL_37_AND_38 =
ADVERTISING_CHANNEL_37 | ADVERTISING_CHANNEL_38,
ADVERTISING_CHANNEL_39 = (1 << 2),
ADVERTISING_CHANNEL_37_AND_39 =
ADVERTISING_CHANNEL_37 | ADVERTISING_CHANNEL_39,
ADVERTISING_CHANNEL_38_AND_39 =
ADVERTISING_CHANNEL_38 | ADVERTISING_CHANNEL_39,
ALL_ADVERTISING_CHANNELS =
ADVERTISING_CHANNEL_37 | ADVERTISING_CHANNEL_38 | ADVERTISING_CHANNEL_39
};
/**
* Construct a new advertising_channel_map_t instance.
*/
advertising_channel_map_t(type value) :
SafeEnum<advertising_channel_map_t, uint8_t>(value) { }
};
/**
* HCI Error codes.
*/
struct hci_error_code_t : SafeEnum<hci_error_code_t, uint8_t> {
enum type {
SUCCESS = 0x00,
UNKNOWN_HCI_COMMAND = 0x01,
UNKNOWN_CONNECTION_IDENTIFIER = 0x02,
HARDWARE_FAILLURE = 0x03,
PAGE_TIMEOUT = 0x04,
AUTHENTICATION_FAILLURE = 0x05,
PIN_OR_KEY_MISSING = 0x06,
MEMORY_CAPACITY_EXCEEDED = 0x07,
CONNECTION_TIMEOUT = 0x08,
CONNECTION_LIMIT_EXCEEDED = 0x09,
SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED = 0x0A,
CONNECTION_ALREADY_EXIST = 0x0B,
COMMAND_DISALLOWED = 0x0C,
CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES = 0x0D,
CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS = 0x0E,
CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR = 0x0F,
CONNECTION_ACCEPT_TIMEOUT_EXCEEDED = 0x10,
UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE = 0x11,
INVALID_HCI_COMMAND_PARAMETERS = 0x12,
REMOTE_USER_TERMINATED_CONNECTION = 0x13,
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES = 0x14,
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF = 0x15,
CONNECTION_TERMINATED_BY_LOCAL_HOST = 0x16,
REPEATED_ATTEMPTS = 0x17,
PAIRING_NOT_ALLOWED = 0x18,
UNKNOWN_LMP_PDU = 0x19,
UNSUPPORTED_REMOTE_FEATURE = 0x1A,
UNSUPPORTED_LMP_FEATURE = 0x1A,
SCO_OFFSET_REJECTED = 0x1B,
SCO_INTERVAL_REJECTED = 0x1C,
SCO_AIR_MODE_REJECTED = 0x1D,
INVALID_LMP_PARAMETERS = 0x1E,
INVALID_LL_PARAMETERS = 0x1E,
UNSPECIFIED_ERROR = 0x1F,
UNSUPPORTED_LMP_PARAMETER_VALUE = 0x20,
UNSUPPORTED_LL_PARAMETER_VALUE = 0x20,
ROLE_CHANGE_NOT_ALLOWED = 0x21,
LMP_RESPONSE_TIMEOUT = 0x22,
LL_RESPONSE_TIMEOUT = 0x22,
LMP_ERROR_TRANSACTION_COLLISION = 0x23,
LL_PROCEDURE_COLLISION = 0x23,
LMP_PDU_NOT_ALLOWED = 0x24,
ENCRYPTION_MODE_NOT_ACCEPTABLE = 0x25,
LINK_KEY_CANNOT_BE_CHANGED = 0x26,
REQUESTED_QOS_NOT_SUPPORTED = 0x27,
INSTANT_PASSED = 0x28,
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
DIFFERENT_TRANSACTION_COLLISION = 0x2A,
RESERVED_FOR_FUTURE_USE = 0x2B,
QOS_UNACCEPTABLE_PARAMETER = 0x2C,
QOS_REJECTED = 0x2D,
CHANNEL_CLASSIFICATION_NOT_SUPPORTED = 0x2E,
INSUFFICIENT_SECURITY = 0x2F,
PARAMETER_OUT_OF_MANDATORY_RANGE = 0x30,
//RESERVED_FOR_FUTURE_USE = 0x31,
ROLE_SWITCH_PENDING = 0x32,
//RESERVED_FOR_FUTURE_USE = 0x33,
RESERVED_SLOT_VIOLATION = 0x34,
ROLE_SWITCH_FAILED = 0x35,
EXTENDED_INQUIRY_RESPONSE_TOO_LARGE = 0x36,
SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST = 0x37,
HOST_BUSY_PAIRING = 0x38,
CONNECTION_REJECTED_DUE_TO_NO_SUITABLE_CHANNEL_FOUND = 0x39,
CONTROLLER_BUSY = 0x3A,
UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B,
ADVERTISING_TIMEOUT = 0x3C,
CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE = 0x3D,
CONNECTION_FAILED_TO_BE_ESTABLISHED = 0x3E,
MAC_CONNECTION_FAILED = 0x3F,
COARSE_CLOCK_ADJUSTMENT_REJECTED_BUT_WILL_TRY_TO_ADJUST_USING_CLOCK_DRAGGING = 0x40,
TYPE0_SUBMAP_NOT_DEFINED = 0x41,
UNKNOWN_ADVERTISING_IDENTIFIER = 0x42,
LIMIT_REACHED = 0x43,
OPERATION_CANCELLED_BY_HOST = 0x44
};
/**
* Construct a new hci_error_code_t instance.
*/
hci_error_code_t(type value) :
SafeEnum<hci_error_code_t, uint8_t>(value) { }
};
/**
* Reasons which can be used to end a connection.
*/
struct disconnection_reason_t : SafeEnum<disconnection_reason_t, uint8_t> {
enum type {
AUTHENTICATION_FAILLURE = 0x05,
REMOTE_USER_TERMINATED_CONNECTION = 0x13,
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES = 0x14,
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF = 0x15,
UNSUPPORTED_REMOTE_FEATURE = 0x1A,
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
};
/**
* Construct a new disconnection_reason_t instance.
*/
disconnection_reason_t(type value) :
SafeEnum<disconnection_reason_t, uint8_t>(value) { }
};
/**
* Filter policy which can be used during advertising.
*/
struct advertising_filter_policy_t :
SafeEnum<advertising_filter_policy_t, uint8_t> {
enum type {
/**
* Process connection and scan requests from all devices. The whitelist is
* not used.
*/
NO_FILTER = 0x00,
/**
* Process connection requests from all devices but filter out scan requests
* of devices which are not in the whitelist.
*/
FILTER_SCAN_REQUESTS = 0x01,
/**
* Process scan requests from all devices but filter out connection requests
* of devices which are not in the whitelist.
*/
FILTER_CONNECTION_REQUEST = 0x02,
/**
* Filter out scan or connection requests of devices which are not in the
* whitelist.
*/
FILTER_SCAN_AND_CONNECTION_REQUESTS = 0x03
};
/**
* Construct a new instance of advertising_filter_policy_t.
*/
advertising_filter_policy_t(type value) :
SafeEnum<advertising_filter_policy_t, uint8_t>(value) { }
};
/**
* Filter policy which can be used during a scan.
*/
struct scanning_filter_policy_t : SafeEnum<scanning_filter_policy_t, uint8_t> {
enum type {
/**
* Accept all advertising packets except directed advertising packet not
* addressed to this device.
*/
NO_FILTER = 0x00,
/**
* Accept only advertising packets from devices in the whitelist except
* directed advertising packet not addressed to this device.
*/
FILTER_ADVERTISING = 0x01
// EXTENDED ADVERTISING FILTER POLICY (accept private resolvable direct advertising)
};
/**
* Construct a new instance of scanning_filter_policy_t.
*/
scanning_filter_policy_t(type value) :
SafeEnum<scanning_filter_policy_t, uint8_t>(value) { }
};
/**
* Filter policy which can be used during connection initiation.
*/
struct initiator_policy_t : SafeEnum<initiator_policy_t, uint8_t> {
enum type {
/**
* The whitelist is not used to determine which advertiser to connect to.
*/
NO_FILTER,
/**
* Whitelist is used to determine which advertiser to connect to.
*/
USE_WHITE_LIST
};
initiator_policy_t(type value) :
SafeEnum<initiator_policy_t, uint8_t>(value) { }
};
/**
* MAC address data type.
*/
struct address_t {
/**
* Create an invalid mac address, equal to FF:FF:FF:FF:FF:FF
*/
address_t() {
memset(value, 0xFF, sizeof(value));
}
/**
* Initialize a mac address from an array of bytes.
*
* @param input_value value of the MAC address.
*/
address_t(const uint8_t (&input_value)[6]) {
memcpy(value, input_value, sizeof(value));
}
/**
* Initialize a mac address from a pointer to a buffer.
*
* @param input_value Buffer containing the mac address. It shall be at
* least 6 long.
*
* @param tag Tag used to select this constructor. The value does not matter.
*/
address_t(const uint8_t* input_value, bool tag) {
memcpy(value, input_value, sizeof(value));
}
/**
* Equal operator between two addresses.
*/
friend bool operator==(const address_t& lhs, const address_t& rhs) {
return memcmp(lhs.value, rhs.value, sizeof(lhs.value)) == 0;
}
/**
* Non equal operator between two addresses.
*/
friend bool operator!=(const address_t& lhs, const address_t& rhs) {
return !(lhs == rhs);
}
/**
* Subscript operator to access mac address content
*/
uint8_t operator[](uint8_t i) const {
return value[i];
}
/**
* Return the pointer to the buffer holding mac address.
*/
const uint8_t* data() const {
return value;
}
/**
* Size in byte of a mac address.
*/
static uint8_t size() {
return sizeof(value);
}
private:
uint8_t value[6];
};
/**
* Hold advertising data.
*/
struct advertising_data_t {
/**
* Construct advertising data from an array.
*
* @param input_value Reference to the array containing the advertising data
*/
advertising_data_t(const uint8_t (&input_value)[31]) {
memcpy(value, input_value, sizeof(value));
}
/**
* Construct advertising data from a pointer to a buffer.
*
* @param input_value Pointer to the buffer containing the advertising data.
*
* @param len Length of the buffer.
*/
advertising_data_t(const uint8_t* input_value, size_t len) {
const size_t actual_len = std::min(len, sizeof(value));
memcpy(value, input_value, actual_len);
memset(value + actual_len, 0x00, sizeof(value) - actual_len);
}
/**
* Equal operator between two advertising data.
*/
friend bool operator==(
const advertising_data_t& lhs, const advertising_data_t& rhs
) {
return memcmp(lhs.value, rhs.value, sizeof(lhs.value)) == 0;
}
/**
* Non equal operator between two advertising data.
*/
friend bool operator!=(
const advertising_data_t& lhs, const advertising_data_t& rhs
) {
return !(lhs == rhs);
}
/**
* Subscript operator used to access the content of the advertising data.
*/
uint8_t operator[](uint8_t i) const {
return value[i];
}
/**
* Return a pointer to the advertising data buffer.
*/
const uint8_t* data() const {
return value;
}
/**
* Return (fixed) size of advertising data.
*/
static uint8_t size() {
return sizeof(value);
}
private:
uint8_t value[31];
};
/**
* Type of advertising the LE subsystem can use when it advertise.
*/
struct received_advertising_type_t :
SafeEnum<received_advertising_type_t, uint8_t> {
enum type {
/**
* Connectable and scannable undirected advertising .
*/
ADV_IND = 0x00,
/**
* Connectable high duty cycle directed advertising
*/
ADV_DIRECT_IND = 0x01,
/**
* Scannable undirected advertising
*/
ADV_SCAN_IND = 0x02,
/**
* Non connectable undirected advertising
*/
ADV_NONCONN_IND = 0x03,
/**
* Response to a scan request.
*/
SCAN_RESPONSE = 0x04
};
/**
* Construct a new received_advertising_type_t value.
*/
received_advertising_type_t(type value) :
SafeEnum<received_advertising_type_t, uint8_t>(value) { }
};
/**
* Model connection role. Used in GapConnectionCompleteEvent.
*/
struct connection_role_t : SafeEnum<connection_role_t, uint8_t> {
enum type {
MASTER,
SLAVE
};
connection_role_t(type value) : SafeEnum<connection_role_t, uint8_t>(value) { }
};
} // namespace pal
} // namespace ble
#endif /* BLE_PAL_GAP_TYPES_H_ */

View File

@ -0,0 +1,696 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_PAL_GAP_H_
#define BLE_PAL_GAP_H_
#include "platform/Callback.h"
#include "GapTypes.h"
#include "GapEvents.h"
namespace ble {
namespace pal {
/**
* Adaptation interface for the GAP layer.
*
* Define the primitive necessary to realize GAP operations. the API and event
* follow closely the definition of the HCI commands and events used
* by that layer.
*/
struct Gap {
/**
* Initialisation of the instance. An implementation can use this function
* to initialise the subsystems needed to realize the operations of this
* interface.
*
* This function has to be called before any other operations.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*/
virtual ble_error_t initialize() = 0;
/**
* Termination of the instance. An implementation can use this function
* to release the subsystems initialised to realise the operations of
* this interface.
*
* After a call to this function, initialise should be called again to
* allow use of the interface.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*/
virtual ble_error_t terminate() = 0;
/**
* Return the public device address.
*
* @note The public device address is usually acquired at initialization and
* stored in the instance.
*
* @return the public device address.
*/
virtual address_t get_device_address() = 0;
/**
* Return the current random address.
*
* @note The random address is usually acquired at initialization and stored
* in the instance.
*
* @return the random device address.
*/
virtual address_t get_random_address() = 0;
/**
* Set the random address which will used be during scan, connection or
* advertising process if the own address type selected is random.
*
* Changing the address during scan, connection or advertising process is
* forbiden.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.4 LE set random address command.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*/
virtual ble_error_t set_random_address(const address_t& address) = 0;
/**
* Set the advertising parameters which will be used during the advertising
* process.
*
* @param advertising_interval_min: Minimum advertising interval which can
* be used during undirected and low duty cycle directed advertising. This
* parameter shall be less than or equal to advertising_interval_max. This
* parameter shall be in the range [0x20 : 0x4000] where each unit is equal
* to 0.625ms.
* This parameter is not used by directed high duty cycle advertising.
*
* @param advertising_interval_max: Maximum advertising interval which can
* be used during undirected and low duty cycle directed advertising. This
* parameter shall be more than or equal to advertising_interval_min. This
* parameter shall be in the range [0x20 : 0x4000] where each unit is equal
* to 0.625ms.
* This parameter is not used by directed high duty cycle advertising.
*
* @param advertising_type Packet type that is used during the
* advertising process. Direct advertising require valid peer addresses
* parameters and ignore the filter policy set.
* If the High duty cycle advertising is used then the advertising parameter
* intervals are ignored.
*
* @param own_address_type Own address type used during advertising.
* If own address type is equal to RESOLVABLE_PRIVATE_ADDRESS_PUBLIC_FALLBACK
* or RESOLVABLE_PRIVATE_ADDRESS_RANDOM_FALLBACK then the peer address
* parameters (type and address) will be used to find the local IRK.
*
* @param peer_address_type Address type of the peer.
* This parameter shall be valid if directed advertising is used (
* ADV_DIRECT_IND or ADV_DIRECT_IND_LOW_DUTY_CYCLE). This parameter should
* be valid if the own address type is equal to 0x02 or 0x03.
* In other cases, this parameter is ignored.
*
* @param peer_address Public device address, Random device addres, Public
* identity address or Random static identity address of the device targeted
* by the advertising.
* This parameter shall be valid if directed advertising is used (
* ADV_DIRECT_IND or ADV_DIRECT_IND_LOW_DUTY_CYCLE). This parameter should
* be valid if the own address type is equal to 0x02 or 0x03.
* In other cases, this parameter is ignored.
*
* @param advertising_channel_map Map of the channel used to send
* advertising data.
*
* @param advertising_filter_policy Filter policy applied during the
* advertising process. The subsystem should use the whitelist to apply the
* policy. This parameter is ignored if the advertising type is directed (
* ADV_DIRECT_IND or ADV_DIRECT_IND_LOW_DUTY_CYCLE).
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.5 LE set advertising parameters
* command.
*/
virtual ble_error_t set_advertising_parameters(
uint16_t advertising_interval_min,
uint16_t advertising_interval_max,
advertising_type_t advertising_type,
own_address_type_t own_address_type,
advertising_peer_address_type_t peer_address_type,
const address_t& peer_address,
advertising_channel_map_t advertising_channel_map,
advertising_filter_policy_t advertising_filter_policy
) = 0;
/**
* Set the data sends in advertising packet. If the advertising is
* currently enabled, the data shall be used when a new advertising packet
* is issued.
*
* @param advertising_data_length Number of significant bytes in the
* advertising data.
*
* @param advertising_data The data sends in advertising packets. Non
* significant bytes shall be equal to 0.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.5 LE set advertising data
* command.
*/
virtual ble_error_t set_advertising_data(
uint8_t advertising_data_length,
const advertising_data_t& advertising_data
) = 0;
/**
* Set the data sends in scan response packets. If the advertising is
* currently enabled, the data shall be used when a new scan response is
* issued.
*
* @param scan_response_data_length Number of significant bytes in the
* scan response data.
*
* @param scan_response_data The data sends in scan response packets. Non
* significant bytes shall be equal to 0.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.8 LE set scan response data
* command.
*/
virtual ble_error_t set_scan_response_data(
uint8_t scan_response_data_length,
const advertising_data_t& scan_response_data
) = 0;
/**
* Start or stop advertising.
*
* The process use advertising and scan response data set with
* set_advertising_data and set_scan_response_data while the parameters used
* are the one set by set_advertising_parameters.
*
* The advertising shall continue until:
* - The advertising is manually disabled (advertising_enable(false)).
* - A connection is created.
* - Time out in case of high duty cycle directed advertising.
*
* If the random address has not been set and the advertising parameter
* own_address_type is set to 0x01 then the procedure shall fail.
*
* If the random address has not been set and the advertising parameter
* own_address_type is set to RESOLVABLE_PRIVATE_ADDRESS_RANDOM_FALLBACK and
* the peer address is not in the resolving list then the procedure shall
* fail.
*
* @param enable If true start the advertising process, if the process was
* already runing and own_address_type is equal to 0x02 or 0x03, the
* subsystem can change the random address.
* If false and the advertising is running then the process should be
* stoped.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.9 LE set advertising enable
* command.
*
* @note If the advertising type is ADV_DIRECT_IND and the connection is not
* created during the time allowed to the procedure then a
* ConnectionComplete event shall be emmited with its error code set to
* ADVERTISING_TIMEOUT.
*
* @note Successfull connection shall emit a ConnectionComplete event. It
* also means advertising is disabled.
*/
virtual ble_error_t advertising_enable(bool enable) = 0;
/**
* Set the parameter of the scan process.
*
* This command shall not be effective when the scanning process is running.
*
* @param active_scanning If true the subsystem does active scanning and
* the bluetooth subsystem shall send scanning PDUs. It shall also listen
* to scan responses. If false no scanning PDUs are sent during the scan
* process.
*
* @param scan_interval The time interval between two subsequent LE scans in
* unit of 0.625ms. This parameter shall be in the range [0x0004 : 0x4000].
*
* @param scan_window Duration of the LE scan. It shall be less than or
* equal to scan_interval value. This parameter shall be in the range
* [0x0004 : 0x4000] and is in unit of 0.625ms.
*
* @param own_address_type Own address type used in scan request packets.
*
* @param filter_policy Filter policy applied when scanning.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.10 LE set scan parameters
* command.
*/
virtual ble_error_t set_scan_parameters(
bool active_scanning,
uint16_t scan_interval,
uint16_t scan_window,
own_address_type_t own_address_type,
scanning_filter_policy_t filter_policy
) = 0;
/**
* Start/stop scanning process.
*
* Parameters of the scanning process shall be set before the scan launch
* by using the function set_scan_parameters.
*
* @parameter enable Start the scanning process if true and stop it if
* false. If the scan process is already started, enabling it again will
* only update the duplicate filtering; based on the new parameter.
*
* @parameter filter_duplicates Enable duplicate filtering if true,
* otherwise disable it.
*
* @important advertising data or scan response data is not considered
* significant when determining duplicate advertising reports.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.11 LE set scan enable command.
*/
virtual ble_error_t scan_enable(
bool enable,
bool filter_duplicates
) = 0;
/**
* Create a new le connection to a connectable advertiser.
*
* @param scan_interval Hint to the le subsystem indicating how
* frequently it should scan for the peer address. It represent the time
* interval between two subsequent scan for the peer. It shall be in the
* range [0x0004 : 0x4000] and the time is in unit of 0.625ms.
*
* @param scan_window Hint to the le subsystem indicating for how long it
* should scan during a scan interval. The value shall be smaller or equal
* to scan_interval. If it is equal to scan_interval then scanning should
* run continuously. It shall be in the range [0x0004 : 0x4000] and the time
* is in unit of 0.625ms.
*
* @param initiator_policy Used to determine if the whitelist is used to
* determine the address to connect to. If the whitelist is not used, the
* connection shall be made against an advertiser matching the peer_address
* and the peer_address_type parameters. Otherwise those parameters are
* ignored.
*
* @param peer_address_type Type of address used by the advertiser. Not used
* if initiator_policy use the whitelist.
*
* @param Address used by the advertiser in its advertising packets. Not
* used if initiator_policy use the whitelist.
*
* @param own_address_type Type of address used in the connection request
* packet.
*
* @param connection_interval_min Minimum interval between two connection
* events allowed for the connection. It shall be less than or equal to
* connection_interval_max. This value shall be in range [0x0006 : 0x0C80]
* and is in unit of 1.25ms.
*
* @param connection_interval_max Maximum interval between two connection
* events allowed for the connection. It shall be greater than or equal to
* connection_interval_min. This value shall be in range [0x0006 : 0x0C80]
* and is in unit of 1.25ms.
*
* @param connection_latency Number of connection events the slave can drop
* if it has nothing to communicate to the master. This value shall be in
* the range [0x0000 : 0x01F3].
*
* @param supervision_timeout Link supervision timeout for the connection.
* It shall be larger than:
* (1 + connection_latency) * connection_interval_max * 2
* Note: connection_interval_max is in ms in this formulae.
* Everytime the master or the slave receive a valid packet from the peer,
* the supervision timer is reset. If the supervision timer reaches
* supervision_timeout then the connection is considered lost and a
* disconnect event shall be emmited.
* This value shall be in the range [0x000A : 0x0C80] and is in unit of 10
* ms.
*
* @param minimum_connection_event_length Informative parameter of the
* minimum length a connection event. It shall be less than or equal to
* maximum_connection_event_length. It shall be in the range
* [0x0000 : 0xFFFF]. It should also be less than the expected connection
* interval. The unit is 0.625ms.
*
* @param maximum_connection_event_length Informative parameter of the
* maximum length a connection event. It shall be more than or equal to
* minimum_connection_event_length. It shall be in the range
* [0x0000 : 0xFFFF]. It should also be less than the expected connection
* interval. The unit is 0.625ms.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.12 LE create connection command.
*/
virtual ble_error_t create_connection(
uint16_t scan_interval,
uint16_t scan_window,
initiator_policy_t initiator_policy,
connection_peer_address_type_t peer_address_type,
const address_t& peer_address,
own_address_type_t own_address_type,
uint16_t connection_interval_min,
uint16_t connection_interval_max,
uint16_t connection_latency,
uint16_t supervision_timeout,
uint16_t minimum_connection_event_length,
uint16_t maximum_connection_event_length
) = 0;
/**
* Cancel the ongoing connection creation process.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.13 LE create connection cancel
* command.
*/
virtual ble_error_t cancel_connection_creation() = 0;
/**
* Return the number of total whitelist entries that can be stored in the
* le subsystem.
*
* @note The value returned can change over time.
*
* @return The number of entries that can be stored in the LE subsystem. It
* range from 0x01 to 0xFF.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.14 LE read white list size
* command.
*/
virtual uint8_t read_white_list_capacity() = 0;
/**
* Clear the whitelist stored in the LE subsystem.
*
* @important This command shall not be issued if the whitelist is being
* used by the advertising, scanning or connection creation procedure.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.15 LE clear white list command.
*/
virtual ble_error_t clear_whitelist() = 0;
/**
* Add a device to the LE subsystem Whitelist.
*
* @param address_type address_type Type of the address to add in the
* whitelist.
*
* @param address Address of the device.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @important This command shall not be issued if the whitelist is being
* used by the advertising, scanning or connection creation procedure.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.16 LE add device to white list
* command.
*/
virtual ble_error_t add_device_to_whitelist(
whitelist_address_type_t address_type,
address_t address
) = 0;
/**
* Remove a device from the LE subsystem Whitelist.
*
* @param address_type address_type Type of the address of the device to
* remove from the whitelist.
*
* @param address Address of the device to remove from the whitelist
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @important This command shall not be issued if the whitelist is being
* used by the advertising, scanning or connection creation procedure.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.17 LE remove device from white
* list command.
*/
virtual ble_error_t remove_device_from_whitelist(
whitelist_address_type_t address_type,
address_t address
) = 0;
/**
* Start a connection update procedure.
*
* This procedure change the parameter used for a connection it can be
* master or slave initiated.
*
* The peer will received a connection parameters request and will either
* accept or reject the new parameters for the connection.
*
* Once the peer response has been received, the procedure ends and a
* Connection update complete event is emmited.
*
* @param connection Handle of the connection.
*
* @param connection_interval_min Minimum interval between two connection
* events allowed for the connection. It shall be less than or equal to
* connection_interval_max. This value shall be in range [0x0006 : 0x0C80]
* and is in unit of 1.25ms.
*
* @param connection_interval_max Maximum interval between two connection
* events allowed for the connection. It shall be greater than or equal to
* connection_interval_min. This value shall be in range [0x0006 : 0x0C80]
* and is in unit of 1.25ms.
*
* @param connection_latency Number of connection events the slave can drop
* if it has nothing to communicate to the master. This value shall be in
* the range [0x0000 : 0x01F3].
*
* @param supervision_timeout Link supervision timeout for the connection.
* It shall be larger than:
* (1 + connection_latency) * connection_interval_max * 2
* Note: connection_interval_max is in ms in this formulae.
* Everytime the master or the slave receive a valid packet from the peer,
* the supervision timer is reset. If the supervision timer reaches
* supervision_timeout then the connection is considered lost and a
* disconnect event shall be emmited.
* This value shall be in the range [0x000A : 0x0C80] and is in unit of 10
* ms.
*
* @param minimum_connection_event_length Informative parameter of the
* minimum length a connection event. It shall be less than or equal to
* maximum_connection_event_length. It shall be in the range
* [0x0000 : 0xFFFF]. It should also be less than the expected connection
* interval. The unit is 0.625ms.
*
* @param maximum_connection_event_length Informative parameter of the
* maximum length a connection event. It shall be more than or equal to
* minimum_connection_event_length. It shall be in the range
* [0x0000 : 0xFFFF]. It should also be less than the expected connection
* interval. The unit is 0.625ms.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.18 LE Connection update command.
*
*/
virtual ble_error_t connection_parameters_update(
connection_handle_t connection,
uint16_t connection_interval_min,
uint16_t connection_interval_max,
uint16_t connection_latency,
uint16_t supervision_timeout,
uint16_t minimum_connection_event_length,
uint16_t maximum_connection_event_length
) = 0;
/**
* Accept connection parameter request.
*
* This command sends a positive response to a connection parameter request
* from a peer.
*
* @param connection Handle of the connection.
*
* @param connection_interval_min Minimum interval between two connection
* events allowed for the connection. It shall be less than or equal to
* connection_interval_max. This value shall be in range [0x0006 : 0x0C80]
* and is in unit of 1.25ms.
*
* @param connection_interval_max Maximum interval between two connection
* events allowed for the connection. It shall be greater than or equal to
* connection_interval_min. This value shall be in range [0x0006 : 0x0C80]
* and is in unit of 1.25ms.
*
* @param connection_latency Number of connection events the slave can drop
* if it has nothing to communicate to the master. This value shall be in
* the range [0x0000 : 0x01F3].
*
* @param supervision_timeout Link supervision timeout for the connection.
* It shall be larger than:
* (1 + connection_latency) * connection_interval_max * 2
* Note: connection_interval_max is in ms in this formulae.
* Everytime the master or the slave receive a valid packet from the peer,
* the supervision timer is reset. If the supervision timer reaches
* supervision_timeout then the connection is considered lost and a
* disconnect event shall be emmited.
* This value shall be in the range [0x000A : 0x0C80] and is in unit of 10
* ms.
*
* @param minimum_connection_event_length Informative parameter of the
* minimum length a connection event. It shall be less than or equal to
* maximum_connection_event_length. It shall be in the range
* [0x0000 : 0xFFFF]. It should also be less than the expected connection
* interval. The unit is 0.625ms.
*
* @param maximum_connection_event_length Informative parameter of the
* maximum length a connection event. It shall be more than or equal to
* minimum_connection_event_length. It shall be in the range
* [0x0000 : 0xFFFF]. It should also be less than the expected connection
* interval. The unit is 0.625ms.
*
* @note Usually parameters of this function match the connection parameters
* received in the connection parameter request event.
*
* @important: Once the new connection parameters are in used a Connection
* Update Complete event shall be emmited.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.31 LE remote connection parameter
* request reply command.
*/
virtual ble_error_t accept_connection_parameter_request(
connection_handle_t connection_handle,
uint16_t interval_min,
uint16_t interval_max,
uint16_t latency,
uint16_t supervision_timeout,
uint16_t minimum_connection_event_length,
uint16_t maximum_connection_event_length
) = 0;
/**
* Reject a connection parameter update request.
*
* @param connection_handle handle to the peer which has issued the
* connection parameter request.
*
* @param rejection_reason Indicate to the peer why the proposed connection
* parameters were rejected.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.8.32 LE Remote Connection Parameter
* Request Negative Reply Command.
*/
virtual ble_error_t reject_connection_parameter_request(
connection_handle_t connection_handle,
hci_error_code_t rejection_reason
) = 0;
/**
* Start a disconnection procedure.
*
* Once the procedure is complete it should emit a disconnection complete
* event.
*
* @param connection Handle of the connection to terminate.
*
* @param disconnection_reason Indicates the reason for ending the
* connection.
*
* @return BLE_ERROR_NONE if the request has been successfully sent or the
* appropriate error otherwise.
*
* @note: See Bluetooth 5 Vol 2 PartE: 7.1.6 disconenct command.
*/
virtual ble_error_t disconnect(
connection_handle_t connection,
disconnection_reason_t disconnection_reason
) = 0;
/**
* Register a callback which will handle Gap events.
*
* @param cb The callback object which will handle Gap events from the
* LE subsystem.
* It accept a single parameter in input: The event received.
*/
void when_gap_event_received(mbed::Callback<void(const GapEvent&)> cb)
{
_gap_event_cb = cb;
}
protected:
Gap() { }
virtual ~Gap() { }
/**
* Implementation shall call this function whenever the LE subsystem
* generate a Gap event.
*
* @param gap_event The event to emit to higher layer.
*/
void emit_gap_event(const GapEvent& gap_event)
{
if (_gap_event_cb) {
_gap_event_cb(gap_event);
}
}
private:
/**
* Callback called when an event is emitted by the LE subsystem.
*/
mbed::Callback<void(const GapEvent&)> _gap_event_cb;
// Disallow copy construction and copy assignment.
Gap(const Gap&);
Gap& operator=(const Gap&);
};
} // namespace pal
} // namespace ble
#endif /* BLE_PAL_GAP_H_ */