mirror of https://github.com/ARMmbed/mbed-os.git
BLE: Introduce GenericGattClient and platform abstraction over ATT/GATT.
This changes introduce a platform adaptation over ATT/GATT that can be implemented by porter. Unlike the GattClient interface, the ATT/GATT adaptation is simple, follow closely the Bluetooth specification and won't change over time. Implementation of the GattClient interface is realized by the class GenericGattClient which accept in input a pal::GattClient. This change will also free design space once adopted by partners, addition to the GattClient interface won't require partner support.pull/5060/head
parent
38bb6b4e52
commit
daaa5b1977
|
@ -0,0 +1,154 @@
|
|||
/* 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 MBED_BLE_GENERIC_GATT_CLIENT
|
||||
#define MBED_BLE_GENERIC_GATT_CLIENT
|
||||
|
||||
#include <algorithm>
|
||||
#include "ble/GattClient.h"
|
||||
#include "ble/pal/PalGattClient.h"
|
||||
|
||||
// IMPORTANT: private header. Not part of the public interface.
|
||||
|
||||
namespace ble {
|
||||
namespace generic {
|
||||
|
||||
// forward declarations
|
||||
struct procedure_control_block_t;
|
||||
struct discovery_control_block_t;
|
||||
struct read_control_block_t;
|
||||
struct write_control_block_t;
|
||||
struct descriptor_discovery_control_block_t;
|
||||
|
||||
/**
|
||||
* Generic implementation of the GattClient.
|
||||
* It requires a pal::GattClient injected at construction site.
|
||||
* @important: Not part of the public interface of BLE API.
|
||||
*/
|
||||
class GenericGattClient : public GattClient {
|
||||
|
||||
// give access to control block classes
|
||||
friend struct procedure_control_block_t;
|
||||
friend struct discovery_control_block_t;
|
||||
friend struct read_control_block_t;
|
||||
friend struct write_control_block_t;
|
||||
friend struct descriptor_discovery_control_block_t;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a GenericGattClient from a pal::GattClient
|
||||
*/
|
||||
GenericGattClient(pal::GattClient* pal_client);
|
||||
|
||||
/**
|
||||
* @see GattClient::launchServiceDiscovery
|
||||
*/
|
||||
virtual ble_error_t launchServiceDiscovery(
|
||||
Gap::Handle_t connection_handle,
|
||||
ServiceDiscovery::ServiceCallback_t service_callback,
|
||||
ServiceDiscovery::CharacteristicCallback_t characteristic_callback,
|
||||
const UUID& matching_service_uuid,
|
||||
const UUID& matching_characteristic_uuid
|
||||
);
|
||||
|
||||
/**
|
||||
* @see GattClient::isServiceDiscoveryActive
|
||||
*/
|
||||
virtual bool isServiceDiscoveryActive() const;
|
||||
|
||||
/**
|
||||
* @see GattClient::terminateServiceDiscovery
|
||||
*/
|
||||
virtual void terminateServiceDiscovery();
|
||||
|
||||
/**
|
||||
* @see GattClient::read
|
||||
*/
|
||||
virtual ble_error_t read(
|
||||
Gap::Handle_t connection_handle,
|
||||
GattAttribute::Handle_t attribute_handle,
|
||||
uint16_t offset
|
||||
) const;
|
||||
|
||||
/**
|
||||
* @see GattClient::write
|
||||
*/
|
||||
virtual ble_error_t write(
|
||||
GattClient::WriteOp_t cmd,
|
||||
Gap::Handle_t connection_handle,
|
||||
GattAttribute::Handle_t attribute_handle,
|
||||
size_t length,
|
||||
const uint8_t* value
|
||||
) const;
|
||||
|
||||
/**
|
||||
* @see GattClient::onServiceDiscoveryTermination
|
||||
*/
|
||||
virtual void onServiceDiscoveryTermination(
|
||||
ServiceDiscovery::TerminationCallback_t callback
|
||||
);
|
||||
|
||||
/**
|
||||
* @see GattClient::discoverCharacteristicDescriptors
|
||||
*/
|
||||
virtual ble_error_t discoverCharacteristicDescriptors(
|
||||
const DiscoveredCharacteristic& characteristic,
|
||||
const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
|
||||
const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
|
||||
);
|
||||
|
||||
/**
|
||||
* @see GattClient::isCharacteristicDescriptorDiscoveryActive
|
||||
*/
|
||||
virtual bool isCharacteristicDescriptorDiscoveryActive(
|
||||
const DiscoveredCharacteristic& characteristic
|
||||
) const;
|
||||
|
||||
/**
|
||||
* @see GattClient::terminateCharacteristicDescriptorDiscovery
|
||||
*/
|
||||
virtual void terminateCharacteristicDescriptorDiscovery(
|
||||
const DiscoveredCharacteristic& characteristic
|
||||
);
|
||||
|
||||
/**
|
||||
* @see GattClient::reset
|
||||
*/
|
||||
virtual ble_error_t reset(void);
|
||||
|
||||
private:
|
||||
procedure_control_block_t* get_control_block(Gap::Handle_t connection);
|
||||
const procedure_control_block_t* get_control_block(Gap::Handle_t connection) const;
|
||||
void insert_control_block(procedure_control_block_t* cb) const;
|
||||
void remove_control_block(procedure_control_block_t* cb) const;
|
||||
|
||||
void on_termination(Gap::Handle_t connection_handle);
|
||||
void on_server_message_received(connection_handle_t, const pal::AttServerMessage&);
|
||||
void on_server_response(connection_handle_t, const pal::AttServerMessage&);
|
||||
void on_server_event(connection_handle_t, const pal::AttServerMessage&);
|
||||
void on_transaction_timeout(connection_handle_t);
|
||||
|
||||
uint16_t get_mtu(Gap::Handle_t connection) const;
|
||||
|
||||
pal::GattClient* const _pal_client;
|
||||
ServiceDiscovery::TerminationCallback_t _termination_callback;
|
||||
mutable procedure_control_block_t* control_blocks;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBED_BLE_GENERIC_GATT_CLIENT */
|
|
@ -0,0 +1,687 @@
|
|||
/* 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_ATTCLIENT_H_
|
||||
#define BLE_PAL_ATTCLIENT_H_
|
||||
|
||||
#include "ble/UUID.h"
|
||||
#include "ble/BLETypes.h"
|
||||
#include "ble/ArrayView.h"
|
||||
#include "ble/blecommon.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "AttServerMessage.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
|
||||
/**
|
||||
* Send attribute protocol requests to an ATT server. It also handle reception
|
||||
* of ATT response and server indication/notification.
|
||||
*
|
||||
* Every request send and response or response event received is for a specified
|
||||
* connection.
|
||||
*
|
||||
* @warning This class should not be used outside mbed BLE, availability is not
|
||||
* guaranteed for all ports.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F
|
||||
*/
|
||||
struct AttClient {
|
||||
/**
|
||||
* Initialization of the instance. An implementation can use this function
|
||||
* to initialise the subsystems needed to realize the ATT 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 ATT operations of
|
||||
* this interface.
|
||||
*
|
||||
* After a call to this function, initialise should be called again to
|
||||
* allow usage 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;
|
||||
|
||||
/**
|
||||
* Send an exchange MTU request which negotiate the size of the MTU used by
|
||||
* the connection.
|
||||
*
|
||||
* First the client send to the server the maximum rx mtu that it can receive
|
||||
* then the client reply with the maximum rx mtu it can receive.
|
||||
*
|
||||
* The mtu choosen for the connection is the minimum of the client Rx mtu
|
||||
* and server Rx mtu values.
|
||||
*
|
||||
* If an error occured then the mtu used remains the default value.
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been succesfully sent or the
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @see ble::pal::AttExchangeMTUResponse The type of response received from
|
||||
* the server
|
||||
* @see ble::pal::AttErrorResponse::REQUEST_NOT_SUPPORTED The error code
|
||||
* returned by the server in case of error.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.2.1
|
||||
*/
|
||||
virtual ble_error_t exchange_mtu_request(connection_handle_t connection) = 0;
|
||||
|
||||
/**
|
||||
* Acquire the size of the mtu for a given connection.
|
||||
*
|
||||
* @param connection The handle of the connection for which the the MTU size
|
||||
* should be acquired.
|
||||
*
|
||||
* @param mtu_size Output parameter which will contain the MTU size.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the MTU size has been acquired or the
|
||||
* appropriate error otherwise.
|
||||
*/
|
||||
virtual ble_error_t get_mtu_size(
|
||||
connection_handle_t connection_handle,
|
||||
uint16_t& mtu_size
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a find information request to a server in order to obtain the
|
||||
* mapping of attribute handles with their associated types.
|
||||
*
|
||||
* The server will reply with a ble::pal::AttFindInformationResponse
|
||||
* containing at least one [attribute handle, attribute type] pair. If the
|
||||
* last handle in the response is not equal to the end handle of the finding
|
||||
* range then this request can be issued again with an updated range (begin
|
||||
* equal to last handle received + 1) to discover the remaining attributes.
|
||||
*
|
||||
* To discover the whole ATT server, the first find information request
|
||||
* should have a discovery range of [0x0001 - 0xFFFF].
|
||||
*
|
||||
* The server can send a ble::pal::AttErrorResponse with the code
|
||||
* ble::pal::AttErrorResponse::ATTRIBUTE_NOT_FOUND if no attributes have
|
||||
* been found in the range specified. The attribute handle in the response
|
||||
* is then equal to the first handle of the discovery range.
|
||||
*
|
||||
* If the range is malformed the server will reply a
|
||||
* ble::pal::AttErrorResponse with the error code ble::pal::INVALID_HANDLE.
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param discovery_range The attribute range where handle-type informations
|
||||
* should be discovered.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or the
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.3.1
|
||||
*/
|
||||
virtual ble_error_t find_information_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a Find By Type Value Request which retrieve the handles of attributes
|
||||
* that have known 16-bit UUID attribute type and known attribute value.
|
||||
*
|
||||
* The server should reply with a ble::pal::AttFindByTypeValueResponse
|
||||
* containing the handle (or handle range in case of grouping attributes) of
|
||||
* the attribute found.
|
||||
*
|
||||
* If not all attributes can be contained in the response it is necessary to
|
||||
* send again this request with an updated range to continue the discovery.
|
||||
*
|
||||
* The server can send a ble::pal::AttErrorResponse with the code
|
||||
* ble::pal::AttErrorResponse::ATTRIBUTE_NOT_FOUND if no attributes have
|
||||
* been found in the range specified. The attribute handle in the response
|
||||
* is then equal to the first handle of the discovery range.
|
||||
*
|
||||
* If the range is malformed the server will reply a
|
||||
* ble::pal::AttErrorResponse with the error code ble::pal::INVALID_HANDLE.
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param discovery_range The handle range where attributes with type and
|
||||
* value are searched.
|
||||
* @param type The type of attribute to find (it is a 16 bit UUID).
|
||||
* @param value The value of the attributes to found.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or the
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.3.3
|
||||
*/
|
||||
virtual ble_error_t find_by_type_value_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range,
|
||||
uint16_t type,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a Read By Type Request used to obtain the values of attributes where
|
||||
* the attribute type is known but the handle is not known.
|
||||
*
|
||||
* If attributes with the type requested are present in the range, the server
|
||||
* should reply with a ble::pal::AttReadByTypeResponse. If the response does
|
||||
* not cover the full range, the request should be sent again with an updated
|
||||
* range.
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::ATTRIBUTE_NOT_FOUND: If there is no
|
||||
* attributes matching type in the range.
|
||||
* - ble::pal::AttErrorResponse::INVALID_HANDLE: If the range is
|
||||
* invalid.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHENTICATION: If the client
|
||||
* security is not sufficient.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHORIZATION: If the client
|
||||
* authorization is not sufficient.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION_KEY_SIZE: If the
|
||||
* client has an insufficient encryption key size.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION: If the client
|
||||
* has not enabled encryption.
|
||||
* - ble::pal::AttErrorResponse::READ_NOT_PERMITTED: If the attribute
|
||||
* value cannot be read.
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param read_range The handle range where attributes with the given type
|
||||
* should be read.
|
||||
* @param type The type of attributes to read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or the
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.1
|
||||
*/
|
||||
virtual ble_error_t read_by_type_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID& type
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a Read Request to read the value of an attribute in the server.
|
||||
*
|
||||
* In case of success, the server will reply with a ble::pal::AttReadResponse.
|
||||
* containing the value of the attribute. If the length of the value in the
|
||||
* response is equal to (mtu - 1) then the remaining part of the value can
|
||||
* be obtained by a read_blob_request.
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::INVALID_HANDLE: If the attribute handle
|
||||
* is invalid.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHENTICATION: If the client
|
||||
* security is not sufficient.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHORIZATION: If the client
|
||||
* authorization is not sufficient.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION_KEY_SIZE: If the
|
||||
* client has an insufficient encryption key size.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION: If the client
|
||||
* has not enabled encryption.
|
||||
* - ble::pal::AttErrorResponse::READ_NOT_PERMITTED: If the attribute
|
||||
* value cannot be read.
|
||||
* Higher layer can also set an application error code (0x80 - 0x9F).
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param attribute_handle The handle of the attribute to read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or the
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.3
|
||||
*/
|
||||
virtual ble_error_t read_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a read blob request to a server to read a part of the value of an
|
||||
* attribute at a given offset.
|
||||
*
|
||||
* In case of success, the server will reply with a ble::pal::AttReadBlobResponse
|
||||
* containing the value read. If the value of the attribute starting at the
|
||||
* offset requested is longer than (mtu - 1) octets then only the first
|
||||
* (mtu - 1) octets will be present in the response.
|
||||
* The remaining octets can be acquired by another Read Blob Request with an
|
||||
* updated index.
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::INVALID_HANDLE: If the attribute handle
|
||||
* is invalid.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHENTICATION: If the client
|
||||
* security is not sufficient.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHORIZATION: If the client
|
||||
* authorization is not sufficient.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION_KEY_SIZE: If the
|
||||
* client has an insufficient encryption key size.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION: If the client
|
||||
* has not enabled encryption.
|
||||
* - ble::pal::AttErrorResponse::READ_NOT_PERMITTED: If the attribute
|
||||
* value cannot be read.
|
||||
* - ble::pal::AttErrorResponse::INVALID_OFFSET: If the offset is greater
|
||||
* than the attribute length.
|
||||
* - ble::pal::AttErrorResponse::ATTRIBUTE_NOT_LONG: If the attribute
|
||||
* value has a length that is less than or equal to (mtu - 1).
|
||||
* Higher layer can also set an application error code (0x80 - 0x9F).
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param attribute_handle The handle of the attribute to read.
|
||||
* @param offset The offset of the first octet to read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.5
|
||||
*/
|
||||
virtual ble_error_t read_blob_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a read multiple request to the server. It is used to read two or more
|
||||
* attributes values at once.
|
||||
*
|
||||
* In case of success, the server will reply with a
|
||||
* ble::pal::AttReadMultipleResponse containing the concatenation of the
|
||||
* values read. Given that values are concatained, all attributes values
|
||||
* should be of fixed size except for the last one. The concatained value
|
||||
* is also truncated to (mtu - 1) if it doesn't fit in the response.
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::INVALID_HANDLE: If any of the attribute
|
||||
* handle is invalid.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHENTICATION: If the client
|
||||
* security is not sufficient to read any of the attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHORIZATION: If the client
|
||||
* authorization is not sufficient to read any of the attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION_KEY_SIZE: If the
|
||||
* client has an insufficient encryption key size to read any of the
|
||||
* attributes.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION: If the client
|
||||
* has not enabled encryption required to read any of the attributes.
|
||||
* - ble::pal::AttErrorResponse::READ_NOT_PERMITTED: If any of the
|
||||
* attributes value cannot be read.
|
||||
* The first attribute causing the error is reporter in the handle_in_error
|
||||
* field in the error response.
|
||||
* Higher layer can also set an application error code (0x80 - 0x9F).
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param attribute_handles Set of attribute handles to read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.7
|
||||
*/
|
||||
virtual ble_error_t read_multiple_request(
|
||||
connection_handle_t connection_handle,
|
||||
const ArrayView<const attribute_handle_t>& attribute_handles
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a read by group type request to the server. It is used to get
|
||||
* informations about grouping attribute of a given type on a server.
|
||||
*
|
||||
* The server will reply with a ble::pal::ReadByGroupTypeResponse containing
|
||||
* informations about the grouping attribute found. Informations are:
|
||||
* - handle of the grouping attribute.
|
||||
* - last handle of the group .
|
||||
* - attribute value.
|
||||
*
|
||||
* If the last handle received is not the last handle of the discovery range
|
||||
* then it is necessary to send another request with a discovery range
|
||||
* updated to: [last handle + 1 : end].
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::INVALID_HANDLE: If the range of handle
|
||||
* provided is invalid.
|
||||
* - ble::pal::AttErrorResponse::UNSUPPORTED_GROUP_TYPE: if the group type
|
||||
* is not a supported grouping attribute.
|
||||
* - ble::pal::AttErrorResponse::ATTRIBUTE_NOT_FOUND: If no attribute with
|
||||
* the given type exists within the range provided.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHENTICATION: If the client
|
||||
* security is not sufficient to read the requested attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHORIZATION: If the client
|
||||
* authorization is not sufficient to read the requested attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION_KEY_SIZE: If the
|
||||
* client has an insufficient encryption key size to read the requested
|
||||
* attributes.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION: If the client
|
||||
* has not enabled encryption required to read the requested attributes.
|
||||
* - ble::pal::AttErrorResponse::READ_NOT_PERMITTED: If any of the
|
||||
* attributes value cannot be read.
|
||||
* Higher layer can also set an application error code (0x80 - 0x9F).
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param read_range Range where this request apply.
|
||||
* @param group_type Type of the grouping attribute to find and read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.9
|
||||
*/
|
||||
virtual ble_error_t read_by_group_type_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID& group_type
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a write request to the server to write the value of an attribute.
|
||||
*
|
||||
* In case of success, the server will reply with a
|
||||
* ble::pal::AttWriteResponse to acknowledge that the write operation went
|
||||
* well.
|
||||
*
|
||||
* If the attribute value has a variable length, then the attribute value
|
||||
* shall be truncated or lengthened to match the length of the value in the
|
||||
* request.
|
||||
*
|
||||
* If the attribute value has a fixed length and the Attribute Value parameter length
|
||||
* is less than or equal to the length of the attribute value, the octets of the
|
||||
* attribute value parameter length shall be written; all other octets in this attribute
|
||||
* value shall be unchanged.
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::INVALID_HANDLE: If the handle to write is
|
||||
* invalid.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHENTICATION: If the client
|
||||
* security is not sufficient to write the requested attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHORIZATION: If the client
|
||||
* authorization is not sufficient to write the requested attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION_KEY_SIZE: If the
|
||||
* client has an insufficient encryption key size to write the requested
|
||||
* attributes.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION: If the client
|
||||
* has not enabled encryption required to write the requested attributes.
|
||||
* - ble::pal::AttErrorResponse::WRITE_NOT_PERMITTED: If the attribute
|
||||
* value cannot be written due to permission.
|
||||
* - ble::pal::AttErrorResponse::INVALID_ATTRIBUTE_VALUE_LENGTH: If the
|
||||
* value to write exceeds the maximum valid length or of the attribute
|
||||
* value; whether the attribute has a variable length value or a fixed
|
||||
* length value.
|
||||
* Higher layer can also set an application error code (0x80 - 0x9F).
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param attribute_handle Handle of the attribute to write.
|
||||
* @param value Value to write. It can't be longer than (mtu - 3).
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.5.1
|
||||
*/
|
||||
virtual ble_error_t write_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a write command to the server. A write command is similar to a write
|
||||
* request except that it won't receive any response from the server
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param attribute_handle Handle of the attribute to write.
|
||||
* @param value Value to write. It can't be longer than (mtu - 3).
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.5.3
|
||||
*/
|
||||
virtual ble_error_t write_command(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a signed write command to the server. Behaviour is similar to a write
|
||||
* command except that 12 bytes of the mtu are reserved for the authentication
|
||||
* signature.
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param attribute_handle Handle of the attribute to write.
|
||||
* @param value Value to write. It can't be longer than (mtu - 15).
|
||||
*
|
||||
* @note the authentication signature to send with this request is
|
||||
* computed by the implementation following the rules defined in BLUETOOTH
|
||||
* SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.3.1.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.5.4
|
||||
*/
|
||||
virtual ble_error_t signed_write_command(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* The Prepare Write Request is used to request the server to prepare to
|
||||
* write the value of an attribute. The client can send multiple prepare
|
||||
* write request which will be put in a queue until the client send an
|
||||
* Execute Write Request which will execute sequentially the write request
|
||||
* in the queue.
|
||||
*
|
||||
* In case of success the server will respond with a
|
||||
* ble::pal::AttPrepareWriteResponse containing the values (attribute handle,
|
||||
* offset and value) present in the write request.
|
||||
*
|
||||
* If a prepare write request is rejected by the server, the state queue of
|
||||
* the prepare write request queue remains unaltered.
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::INVALID_HANDLE: If the handle to write is
|
||||
* invalid.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHENTICATION: If the client
|
||||
* security is not sufficient to write the requested attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_AUTHORIZATION: If the client
|
||||
* authorization is not sufficient to write the requested attribute.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION_KEY_SIZE: If the
|
||||
* client has an insufficient encryption key size to write the requested
|
||||
* attributes.
|
||||
* - ble::pal::AttErrorResponse::INSUFFICIENT_ENCRYPTION: If the client
|
||||
* has not enabled encryption required to write the requested attributes.
|
||||
* - ble::pal::AttErrorResponse::WRITE_NOT_PERMITTED: If the attribute
|
||||
* value cannot be written due to permission.
|
||||
* - ble::pal::PREPARE_QUEUE_FULL: If the queue of prepare write request
|
||||
* is full.
|
||||
* Higher layer can also set an application error code (0x80 - 0x9F).
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param attribute_handle The handle of the attribute to be written.
|
||||
* @param offset The offset of the first octet to be written.
|
||||
* @param value The value of the attribute to be written. It can't be longer
|
||||
* than (mtu - 5).
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.6.1
|
||||
*
|
||||
*/
|
||||
virtual ble_error_t prepare_write_request(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send an Execute Write Request to the server. This request will instruct
|
||||
* the server to execute or cancel the prepare write requests currently held
|
||||
* in the prepare queue from this client.
|
||||
*
|
||||
* If the execute parameter is set to true, the server should execute the
|
||||
* request held in the queue. If the parameter is equal to false then the
|
||||
* server should cancel the requests in the queue.
|
||||
*
|
||||
* In case of success, the server will respond with a
|
||||
* ble::pal::AttExecuteWriteResponse indicating that the request was correctly
|
||||
* handled.
|
||||
*
|
||||
* In case of error, the server will send a ble::pal::AttErrorResponse. The
|
||||
* error code depends on the situation:
|
||||
* - ble::pal::AttErrorResponse::INVALID_OFFSET: If the value offset is
|
||||
* greater than the current length of the attribute to write.
|
||||
* - ble::pal::AttErrorResponse::INVALID_ATTRIBUTE_VALUE_LENGTH: If the
|
||||
* length of the value write exceeds the length of the attribute value
|
||||
* about to be written.
|
||||
* Higher layer can also set an application error code (0x80 - 0x9F).
|
||||
*
|
||||
* The error response will contains the attribute handle which as caused the
|
||||
* error and the remaining of the prepare queue is discarded. The state of
|
||||
* the attributes that were to be written from the prepare queue is not
|
||||
* defined in this case.
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this
|
||||
* request to.
|
||||
* @param execute Boolean indicating if the prepare queue should be executed
|
||||
* or cleared.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the request has been successfully sent or an
|
||||
* appropriate error otherwise.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.6.3
|
||||
*/
|
||||
virtual ble_error_t execute_write_request(
|
||||
connection_handle_t connection_handle,
|
||||
bool execute
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Register a callback which will handle messages from the server.
|
||||
*
|
||||
* @param cb The callback object which will handle messages from the server.
|
||||
* It accept two parameters in input: The handle of the connection where the
|
||||
* message was received and the message received. Real type of the message
|
||||
* can be obtained from its opcode.
|
||||
*/
|
||||
void when_server_message_received(
|
||||
mbed::Callback<void(connection_handle_t, const AttServerMessage&)> cb
|
||||
) {
|
||||
_server_message_cb = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback handling transaction timeout.
|
||||
*
|
||||
* @param cb The callback handling timeout of a transaction. It accepts as
|
||||
* a parameter the connection handle involved in the timeout.
|
||||
*
|
||||
* @note No more attribute protocol requests, commands, indication or
|
||||
* notification shall be sent over a connection implied in a transaction
|
||||
* timeout. To send a new ATT message, the conenction should be
|
||||
* reestablished.
|
||||
*/
|
||||
void when_transaction_timeout(
|
||||
mbed::Callback<void(connection_handle_t)> cb
|
||||
) {
|
||||
_transaction_timeout_cb = cb;
|
||||
}
|
||||
|
||||
protected:
|
||||
AttClient() { }
|
||||
|
||||
virtual ~AttClient() { }
|
||||
|
||||
/**
|
||||
* Upon server message reception an implementation shall call this function.
|
||||
*
|
||||
* @param connection_handle The handle of the connection which has received
|
||||
* the server message.
|
||||
* @param server_message The message received from the server.
|
||||
*/
|
||||
void on_server_event(
|
||||
connection_handle_t connection_handle,
|
||||
const AttServerMessage& server_message
|
||||
) {
|
||||
if (_server_message_cb) {
|
||||
_server_message_cb(connection_handle, server_message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upon transaction timeout an implementation shall call this function.
|
||||
*
|
||||
* @param connection_handle The handle of the connection of the transaction
|
||||
* which has times out.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.3.3
|
||||
*/
|
||||
void on_transaction_timeout(
|
||||
connection_handle_t connection_handle
|
||||
) {
|
||||
if (_transaction_timeout_cb) {
|
||||
_transaction_timeout_cb(connection_handle);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Callback called when the client receive a message from the server.
|
||||
*/
|
||||
mbed::Callback<void(connection_handle_t, const AttServerMessage&)> _server_message_cb;
|
||||
|
||||
/**
|
||||
* Callback called when a transaction times out.
|
||||
*/
|
||||
mbed::Callback<void(connection_handle_t)> _transaction_timeout_cb;
|
||||
|
||||
// Disallow copy construction and copy assignment.
|
||||
AttClient(const AttClient&);
|
||||
AttClient& operator=(const AttClient&);
|
||||
};
|
||||
|
||||
|
||||
} // namespace pal
|
||||
} // namespace ble
|
||||
|
||||
#endif /* BLE_PAL_ATTCLIENT_H_ */
|
|
@ -0,0 +1,297 @@
|
|||
/* 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_ATTCLIENTTOGATTCLIENTADAPTER_H_
|
||||
#define BLE_PAL_ATTCLIENTTOGATTCLIENTADAPTER_H_
|
||||
|
||||
#include "AttClient.h"
|
||||
#include "PalGattClient.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
|
||||
/**
|
||||
* Adapt a pal::AttClient into a pal::GattClient.
|
||||
*
|
||||
* This class let vendors define their abstraction layer in term of an AttClient
|
||||
* and adapt any AttClient into a GattClient.
|
||||
*/
|
||||
class AttClientToGattClientAdapter : public GattClient {
|
||||
|
||||
public:
|
||||
static const uint16_t END_ATTRIBUTE_HANDLE = 0xFFFF;
|
||||
static const uint16_t SERVICE_TYPE_UUID = 0x2800;
|
||||
static const uint16_t INCLUDE_TYPE_UUID = 0x2802;
|
||||
static const uint16_t CHARACTERISTIC_TYPE_UUID = 0x2803;
|
||||
|
||||
/**
|
||||
* Construct an instance of GattClient from an instance of AttClient.
|
||||
* @param client The client to adapt.
|
||||
*/
|
||||
AttClientToGattClientAdapter(AttClient& client) :
|
||||
GattClient(), _client(client) {
|
||||
_client.when_server_message_received(
|
||||
mbed::callback(this, &AttClientToGattClientAdapter::on_server_event)
|
||||
);
|
||||
_client.when_transaction_timeout(
|
||||
mbed::callback(
|
||||
this, &AttClientToGattClientAdapter::on_transaction_timeout
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::exchange_mtu
|
||||
*/
|
||||
virtual ble_error_t exchange_mtu(connection_handle_t connection) {
|
||||
return _client.exchange_mtu_request(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::get_mtu_size
|
||||
*/
|
||||
virtual ble_error_t get_mtu_size(
|
||||
connection_handle_t connection_handle,
|
||||
uint16_t& mtu_size
|
||||
) {
|
||||
return _client.get_mtu_size(connection_handle, mtu_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::discover_primary_service
|
||||
*/
|
||||
virtual ble_error_t discover_primary_service(
|
||||
connection_handle_t connection,
|
||||
attribute_handle_t discovery_range_begining
|
||||
) {
|
||||
return _client.read_by_group_type_request(
|
||||
connection,
|
||||
attribute_handle_range(discovery_range_begining, END_ATTRIBUTE_HANDLE),
|
||||
SERVICE_TYPE_UUID
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::discover_primary_service_by_service_uuid
|
||||
*/
|
||||
virtual ble_error_t discover_primary_service_by_service_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t discovery_range_begining,
|
||||
const UUID& uuid
|
||||
) {
|
||||
return _client.find_by_type_value_request(
|
||||
connection_handle,
|
||||
attribute_handle_range(discovery_range_begining, END_ATTRIBUTE_HANDLE),
|
||||
SERVICE_TYPE_UUID,
|
||||
ArrayView<const uint8_t>(
|
||||
uuid.getBaseUUID(),
|
||||
(uuid.shortOrLong() == UUID::UUID_TYPE_SHORT) ? 2 : UUID::LENGTH_OF_LONG_UUID
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::find_included_service
|
||||
*/
|
||||
virtual ble_error_t find_included_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t service_range
|
||||
) {
|
||||
return _client.read_by_type_request(
|
||||
connection_handle,
|
||||
service_range,
|
||||
INCLUDE_TYPE_UUID
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::discover_characteristics_of_a_service
|
||||
*/
|
||||
virtual ble_error_t discover_characteristics_of_a_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range
|
||||
) {
|
||||
return _client.read_by_type_request(
|
||||
connection_handle,
|
||||
discovery_range,
|
||||
CHARACTERISTIC_TYPE_UUID
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::discover_characteristics_descriptors
|
||||
*/
|
||||
virtual ble_error_t discover_characteristics_descriptors(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t descriptors_discovery_range
|
||||
) {
|
||||
return _client.find_information_request(
|
||||
connection_handle,
|
||||
descriptors_discovery_range
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::read_attribute_value
|
||||
*/
|
||||
virtual ble_error_t read_attribute_value(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle
|
||||
) {
|
||||
return _client.read_request(
|
||||
connection_handle,
|
||||
attribute_handle
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::read_using_characteristic_uuid
|
||||
*/
|
||||
virtual ble_error_t read_using_characteristic_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID& uuid
|
||||
) {
|
||||
return _client.read_by_type_request(
|
||||
connection_handle,
|
||||
read_range,
|
||||
uuid
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::read_attribute_blob
|
||||
*/
|
||||
virtual ble_error_t read_attribute_blob(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset
|
||||
) {
|
||||
return _client.read_blob_request(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
offset
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::read_multiple_characteristic_values
|
||||
*/
|
||||
virtual ble_error_t read_multiple_characteristic_values(
|
||||
connection_handle_t connection_handle,
|
||||
const ArrayView<const attribute_handle_t>& characteristic_value_handles
|
||||
) {
|
||||
return _client.read_multiple_request(
|
||||
connection_handle,
|
||||
characteristic_value_handles
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::write_without_response
|
||||
*/
|
||||
virtual ble_error_t write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) {
|
||||
return _client.write_command(
|
||||
connection_handle,
|
||||
characteristic_value_handle,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::signed_write_without_response
|
||||
*/
|
||||
virtual ble_error_t signed_write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) {
|
||||
return _client.signed_write_command(
|
||||
connection_handle,
|
||||
characteristic_value_handle,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::write_attribute
|
||||
*/
|
||||
virtual ble_error_t write_attribute(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) {
|
||||
return _client.write_request(
|
||||
connection_handle,
|
||||
attribute_handle,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::queue_prepare_write
|
||||
*/
|
||||
virtual ble_error_t queue_prepare_write(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value,
|
||||
uint16_t offset
|
||||
) {
|
||||
return _client.prepare_write_request(
|
||||
connection_handle,
|
||||
characteristic_value_handle,
|
||||
offset,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::execute_write_queue
|
||||
*/
|
||||
virtual ble_error_t execute_write_queue(
|
||||
connection_handle_t connection_handle,
|
||||
bool execute
|
||||
) {
|
||||
return _client.execute_write_request(connection_handle, execute);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::initialize
|
||||
*/
|
||||
virtual ble_error_t initialize() {
|
||||
return _client.initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::GattClient::terminate
|
||||
*/
|
||||
virtual ble_error_t terminate() {
|
||||
return _client.initialize();
|
||||
}
|
||||
|
||||
private:
|
||||
AttClient& _client;
|
||||
};
|
||||
|
||||
} // namespace pal
|
||||
} // namespace ble
|
||||
|
||||
|
||||
#endif /* BLE_PAL_ATTCLIENTTOGATTCLIENTADAPTER_H_ */
|
|
@ -0,0 +1,772 @@
|
|||
/* 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_ATT_SERVER_MESSAGE_H_
|
||||
#define BLE_PAL_ATT_SERVER_MESSAGE_H_
|
||||
|
||||
#include "ble/BLETypes.h"
|
||||
#include "ble/ArrayView.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
|
||||
/**
|
||||
* Operation code defined for attribute operations
|
||||
* @note see: BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.8
|
||||
*/
|
||||
struct AttributeOpcode {
|
||||
enum Code {
|
||||
ERROR_RESPONSE = 0x01, /// Opcode of an AttErrorResponse
|
||||
EXCHANGE_MTU_REQUEST = 0x02,
|
||||
EXCHANGE_MTU_RESPONSE = 0x03, /// OpCode of an AttExchangeMTUResponse
|
||||
FIND_INFORMATION_REQUEST = 0x04,
|
||||
FIND_INFORMATION_RESPONSE = 0x05, /// OpCode of an AttFindInformationResponse
|
||||
FIND_BY_TYPE_VALUE_REQUEST = 0x06,
|
||||
FIND_BY_VALUE_TYPE_RESPONSE = 0x07, /// OpCode of an AttFindByTypeValueResponse
|
||||
READ_BY_TYPE_REQUEST = 0x08,
|
||||
READ_BY_TYPE_RESPONSE = 0x09, /// Opcode of an AttReadByTypeResponse
|
||||
READ_REQUEST = 0x0A,
|
||||
READ_RESPONSE = 0x0B, /// Opcode of an AttReadResponse
|
||||
READ_BLOB_REQUEST = 0x0C,
|
||||
READ_BLOB_RESPONSE = 0x0D, /// Opcode of an AttReadBlobResponse
|
||||
READ_MULTIPLE_REQUEST = 0x0E,
|
||||
READ_MULTIPLE_RESPONSE = 0x0F, /// Opcode of an AttReadMultipleResponse
|
||||
READ_BY_GROUP_TYPE_REQUEST = 0x10,
|
||||
READ_BY_GROUP_TYPE_RESPONSE = 0x11, /// Opcode of an AttReadByGroupTypeResponse
|
||||
WRITE_REQUEST = 0x12,
|
||||
WRITE_RESPONSE = 0x13, /// Opcode of an AttWriteResponse
|
||||
WRITE_COMMAND = 0x52,
|
||||
SIGNED_WRITE_COMMAND = 0xD2,
|
||||
PREPARE_WRITE_REQUEST = 0x16,
|
||||
PREPARE_WRITE_RESPONSE = 0x17, /// Opcode of an AttPrepareWriteResponse
|
||||
EXECUTE_WRITE_REQUEST = 0x18,
|
||||
EXECUTE_WRITE_RESPONSE = 0x19, /// Opcode of an AttExecuteWriteResponse
|
||||
HANDLE_VALUE_NOTIFICATION = 0x1B,
|
||||
HANDLE_VALUE_INDICATION = 0x1D
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an AttributeOpcode from a Code.
|
||||
*/
|
||||
AttributeOpcode(Code value) : _value(value) { }
|
||||
|
||||
/**
|
||||
* Equality comparison operator between two AttributeOpcode
|
||||
*/
|
||||
friend bool operator==(AttributeOpcode lhs, AttributeOpcode rhs) {
|
||||
return lhs._value == rhs._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Non equality comparison operator between two AttributeOpcode
|
||||
*/
|
||||
friend bool operator!=(AttributeOpcode lhs, AttributeOpcode rhs) {
|
||||
return lhs._value != rhs._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* implicit cast to uint8_t.
|
||||
* Allows AttributeOpcode to be used in switch statements.
|
||||
*/
|
||||
operator uint8_t() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t _value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for Attribute Server Message.
|
||||
* The correct type of the instance can be determined with the attribute opcode.
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.3.1
|
||||
*/
|
||||
struct AttServerMessage {
|
||||
/**
|
||||
* Op code used to identify the type of the attribute response.
|
||||
*/
|
||||
const AttributeOpcode opcode;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Construction of an AttResponse is reserved for descendent of the class
|
||||
*/
|
||||
AttServerMessage(AttributeOpcode opcode_) : opcode(opcode_) { }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response to a request which can't be performed
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.1.1
|
||||
* for details about error response.
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.9
|
||||
* which details possible error response by requests.
|
||||
*/
|
||||
struct AttErrorResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct an attribute error response.
|
||||
*
|
||||
* @param request_opcode_ The Attribute opcode of the request that generated
|
||||
* the error.
|
||||
* @param handle_in_error_ The attribute handle that generated this error
|
||||
* response.
|
||||
* @param error_code The reason why the request has generated an error.
|
||||
*/
|
||||
AttErrorResponse(
|
||||
AttributeOpcode request_opcode_,
|
||||
attribute_handle_t handle_in_error_,
|
||||
uint8_t error_code_
|
||||
) : AttServerMessage(AttributeOpcode::ERROR_RESPONSE),
|
||||
request_opcode(request_opcode_),
|
||||
handle_in_error(handle_in_error_), error_code(error_code_) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an attribute error response in the case where there was no
|
||||
* attribute handle in the original response or if the request is not
|
||||
* supported.
|
||||
*
|
||||
* @param request_opcode_ The Attribute opcode of the request that generated
|
||||
* the error.
|
||||
* @param error_code The reason why the request has generated an error.
|
||||
*/
|
||||
AttErrorResponse(
|
||||
AttributeOpcode request_opcode_,
|
||||
uint8_t error_code_
|
||||
) : AttServerMessage(AttributeOpcode::ERROR_RESPONSE),
|
||||
request_opcode(request_opcode_),
|
||||
handle_in_error(0x0000), error_code(error_code_) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The opcode of the request that generated this error response.
|
||||
*/
|
||||
const AttributeOpcode request_opcode;
|
||||
|
||||
/**
|
||||
* The attribute handle that generated this error response.
|
||||
* If there was no attribute handle in the original request or if the
|
||||
* request is not supported, then this field is equal to 0x0000.
|
||||
*/
|
||||
const attribute_handle_t handle_in_error;
|
||||
|
||||
/**
|
||||
* The reason why the request has generated an error response
|
||||
*/
|
||||
const uint8_t error_code;
|
||||
|
||||
/**
|
||||
* List of Error codes for the ATT protocol
|
||||
*/
|
||||
enum AttributeErrorCode {
|
||||
/** The attribute handle given was not valid on this server. */
|
||||
INVALID_HANDLE = 0x01,
|
||||
|
||||
/** The attribute cannot be read. */
|
||||
READ_NOT_PERMITTED = 0x02,
|
||||
|
||||
/** The attribute cannot be written. */
|
||||
WRITE_NOT_PERMITTED = 0x03,
|
||||
|
||||
/** The attribute PDU was invalid. */
|
||||
INVALID_PDU = 0x04,
|
||||
|
||||
/** The attribute requires authentication before it can be read or
|
||||
* written.
|
||||
*/
|
||||
INSUFFICIENT_AUTHENTICATION = 0x05,
|
||||
|
||||
/** Attribute server does not support the request received from the
|
||||
* client.
|
||||
*/
|
||||
REQUEST_NOT_SUPPORTED = 0x06,
|
||||
|
||||
/** Offset specified was past the end of the attribute. */
|
||||
INVALID_OFFSET = 0x07,
|
||||
|
||||
/** The attribute requires authorization before it can be read or written. */
|
||||
INSUFFICIENT_AUTHORIZATION = 0x08,
|
||||
|
||||
/** Too many prepare writes have been queued. */
|
||||
PREPARE_QUEUE_FULL = 0x09,
|
||||
|
||||
/** No attribute found within the given attribute handle range. */
|
||||
ATTRIBUTE_NOT_FOUND = 0x0A,
|
||||
|
||||
/** The attribute cannot be read using the Read Blob Request. */
|
||||
ATTRIBUTE_NOT_LONG = 0x0B,
|
||||
|
||||
/** The Encryption Key Size used for encrypting this link is
|
||||
* insufficient.
|
||||
*/
|
||||
INSUFFICIENT_ENCRYPTION_KEY_SIZE = 0x0C,
|
||||
|
||||
/** The attribute value length is invalid for the operation. */
|
||||
INVALID_ATTRIBUTE_VALUE_LENGTH = 0x0D,
|
||||
|
||||
/** The attribute request that was requested has encountered an error
|
||||
* that was unlikely, and therefore could not be completed as requested.
|
||||
*/
|
||||
UNLIKELY_ERROR = 0x0E,
|
||||
|
||||
/** The attribute requires encryption before it can be read or written. */
|
||||
INSUFFICIENT_ENCRYPTION = 0x0F,
|
||||
|
||||
/** The attribute type is not a supported grouping attribute as defined
|
||||
* by a higher layer specification.
|
||||
*/
|
||||
UNSUPPORTED_GROUP_TYPE = 0x10,
|
||||
|
||||
/** Insufficient Resources to complete the request. */
|
||||
INSUFFICIENT_RESOURCES = 0x11,
|
||||
|
||||
/* 0x12 - 0x7F => reserved for future use */
|
||||
|
||||
/* 0x80 - 0x9F => Application Error */
|
||||
|
||||
/* 0xA0 0xDF => Reserved for future use */
|
||||
|
||||
/* 0xE0 - 0xFF Common Profile and service Error Codes */
|
||||
|
||||
/** The Write Request Rejected error code is used when a requested write
|
||||
* operation cannot be fulfilled for reasons other than permissions.
|
||||
*/
|
||||
WRITE_REQUEST_REJECTED = 0xFC,
|
||||
|
||||
/** The Client Characteristic Configuration Descriptor Improperly
|
||||
* Configured error code is used when a Client Characteristic
|
||||
* Configuration descriptor is not configured according to the
|
||||
* requirements of the profile or service.
|
||||
*/
|
||||
CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR_IMPROPERLY_CONFIGURED = 0xFD,
|
||||
|
||||
/** The Procedure Already in Progress error code is used when a profile
|
||||
* or service request cannot be serviced because an operation that has
|
||||
* been previously triggered is still in progress
|
||||
*/
|
||||
PROCEDURE_ALREADY_IN_PROGRESS = 0xFE,
|
||||
|
||||
/** The Out of Range error code is used when an attribute value is out
|
||||
* of range as defined by a profile or service specification.
|
||||
*/
|
||||
OUT_OF_RANGE = 0xFF
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Exchange MTU Request is used by the client to inform the server of the
|
||||
* client’s maximum receive MTU size and request the server to respond with its
|
||||
* maximum rx MTU size.
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.2.2
|
||||
*/
|
||||
struct AttExchangeMTUResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct an exchange mtu response containing the max rx mtu of the
|
||||
* server.
|
||||
*
|
||||
* @param server_rx_mtu_ The max rx mtu the server can handle.
|
||||
*/
|
||||
AttExchangeMTUResponse(uint16_t server_rx_mtu_) :
|
||||
AttServerMessage(AttributeOpcode::EXCHANGE_MTU_RESPONSE),
|
||||
server_rx_mtu(server_rx_mtu_) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The max rx mtu the server can handle.
|
||||
*/
|
||||
const uint16_t server_rx_mtu;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Find Information Response is sent in reply to a received Find Information
|
||||
* Request and contains information about this server.
|
||||
*
|
||||
* The Find Information Response contains a sequence of handle-uuid pairs in
|
||||
* ascending order if attribute handles.
|
||||
*
|
||||
* This class has to be subclassed by an implementation specific class defining
|
||||
* the member function size and the subscript operator.
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.3.2
|
||||
*/
|
||||
struct AttFindInformationResponse : public AttServerMessage {
|
||||
|
||||
/** handle-uuid pair */
|
||||
struct information_data_t {
|
||||
attribute_handle_t handle;
|
||||
UUID uuid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base constructor, setup the OpCode of the response.
|
||||
*/
|
||||
AttFindInformationResponse() :
|
||||
AttServerMessage(AttributeOpcode::FIND_INFORMATION_RESPONSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* virtual destructor to overide if the sub class needs it.
|
||||
*/
|
||||
virtual ~AttFindInformationResponse() { }
|
||||
|
||||
/**
|
||||
* Returns the number of information_data_t present in the response.
|
||||
*/
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/**
|
||||
* Access to information_data_t elements present in the response.
|
||||
* @note Out of range access is undefined.
|
||||
*/
|
||||
virtual information_data_t operator[](size_t index) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Find by type value responses are sent in response to find by type value
|
||||
* request.
|
||||
*
|
||||
* The response contains a sequence of Found Attribute Handle, Group End Handle
|
||||
* pair where:
|
||||
* - Found Attribute Handle is the handle of an attribute matching the type
|
||||
* and the value requested.
|
||||
* - Group End Handle is the end of the attribute group if the attribute found
|
||||
* is a grouping attribute or the same value as Found Attribute Handle if
|
||||
* the attribute is not a grouping attribute.
|
||||
*
|
||||
* This class should be subclassed by an implementation specific class defining
|
||||
* the member function size and the subscript operator.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.3.4
|
||||
*/
|
||||
struct AttFindByTypeValueResponse : public AttServerMessage {
|
||||
/**
|
||||
* Base constructor, setup the OpCode of the response.
|
||||
*/
|
||||
AttFindByTypeValueResponse() :
|
||||
AttServerMessage(AttributeOpcode::FIND_BY_VALUE_TYPE_RESPONSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* virtual destructor to overide if the sub class needs it.
|
||||
*/
|
||||
virtual ~AttFindByTypeValueResponse() { }
|
||||
|
||||
/**
|
||||
* Returns the number of attribute_handle_range_t present in the response.
|
||||
*/
|
||||
virtual std::size_t size() const = 0;
|
||||
|
||||
/**
|
||||
* Access to the attribute range present in the response.
|
||||
* @note Out of range access is undefined.
|
||||
*/
|
||||
virtual attribute_handle_range_t operator[](size_t index) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response to a Read By Type request.
|
||||
*
|
||||
* It contains a list of handle-value pairs where:
|
||||
* - handle is the handle of the attribute matching the rype requested.
|
||||
* - value is the value of the attribute found. If the value is longer than
|
||||
* (mtu - 4) then it can be truncated and read blob request should be used
|
||||
* to read the remaining octet of the attribute.
|
||||
*
|
||||
* This class has to be subclassed by an implementation specific class defining
|
||||
* the member function size and the subscript operator.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.2
|
||||
*/
|
||||
struct AttReadByTypeResponse : public AttServerMessage {
|
||||
/**
|
||||
* handle-value pair
|
||||
*/
|
||||
struct attribute_data_t {
|
||||
attribute_handle_t handle;
|
||||
ArrayView<const uint8_t> value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base constructor, setup the OpCode of the response.
|
||||
*/
|
||||
AttReadByTypeResponse() :
|
||||
AttServerMessage(AttributeOpcode::READ_BY_TYPE_RESPONSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* virtual destructor to overide if the sub class needs it.
|
||||
*/
|
||||
virtual ~AttReadByTypeResponse() { }
|
||||
|
||||
/**
|
||||
* Return the number of attribute_data_t presents in the response.
|
||||
*/
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/**
|
||||
* Return the attribute data at index.
|
||||
* @note Out of range access is undefined.
|
||||
*/
|
||||
virtual attribute_data_t operator[](size_t index) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The read response is sent in reply to a received Read Request and contains
|
||||
* the value of the attribute that has been read.
|
||||
*
|
||||
* The attribute value shall be set to the value of the attribute identified by
|
||||
* the attribute handle in the request. If the attribute value is longer than
|
||||
* (ATT_MTU-1) then the first (ATT_MTU-1) octets shall be included in this
|
||||
* response.
|
||||
*
|
||||
* @note The Read Blob Request would be used to read the remaining octets of a
|
||||
* long attribute value.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.4
|
||||
*/
|
||||
struct AttReadResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct a Read Response from an array of bytes.
|
||||
*/
|
||||
AttReadResponse(ArrayView<const uint8_t> data_) :
|
||||
AttServerMessage(AttributeOpcode::READ_RESPONSE), _data(data_) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of octets presents in the response.
|
||||
*/
|
||||
size_t size() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the octet at the specified index.
|
||||
* @note Out of range access is undefined.
|
||||
*/
|
||||
uint8_t operator[](size_t index) const {
|
||||
return _data[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pointer to the actual data
|
||||
*/
|
||||
const uint8_t* data() const {
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
private:
|
||||
const ArrayView<const uint8_t> _data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Read Blob Response is sent in reply to a received Read Blob Request and
|
||||
* contains part of the value of the attribute that has been read.
|
||||
*
|
||||
* If the offset requested is equal to the length of the attribute then the
|
||||
* response contains no data and the size of the data returned is equal to 0.
|
||||
*
|
||||
* If the value of the attribute starting at the offset requested is longer than
|
||||
* (mtu - 1) octets then the first (mtu - 1) will be present in the response.
|
||||
* The remaining octets will be acquired by another Read Blob Request with an
|
||||
* updated index.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.6
|
||||
*/
|
||||
struct AttReadBlobResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct a read blob response from the value responded.
|
||||
*/
|
||||
AttReadBlobResponse(ArrayView<const uint8_t> data_) :
|
||||
AttServerMessage(AttributeOpcode::READ_BLOB_RESPONSE), _data(data_) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of octets presents in the response value.
|
||||
*/
|
||||
size_t size() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the octet of the value read at the specified index.
|
||||
* @note Out of range access is undefined.
|
||||
*/
|
||||
uint8_t operator[](size_t index) const {
|
||||
return _data[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pointer to the actual data
|
||||
*/
|
||||
const uint8_t* data() const {
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
private:
|
||||
const ArrayView<const uint8_t> _data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response to a Read Multiple Request. It contains the values of the attributes
|
||||
* that have been read.
|
||||
*
|
||||
* If the set of values that has been read is longer than (mtu - 1) then only
|
||||
* the first (mtu - 1) octets are included in the response.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.8
|
||||
*/
|
||||
struct AttReadMultipleResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct a Resd Multiple Response from the set of value received.
|
||||
*/
|
||||
AttReadMultipleResponse(ArrayView<const uint8_t> data_) :
|
||||
AttServerMessage(AttributeOpcode::READ_MULTIPLE_RESPONSE), _data(data_) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of octets presents in the response set of value.
|
||||
*/
|
||||
size_t size() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the octet of the set of value read at the specified index.
|
||||
* @note Out of range access is undefined.
|
||||
*/
|
||||
uint8_t operator[](size_t index) const {
|
||||
return _data[index];
|
||||
}
|
||||
|
||||
private:
|
||||
const ArrayView<const uint8_t> _data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Read By Group Type Response is sent in reply to a received Read By
|
||||
* Group Type Request and contains the handles and values of the attributes that
|
||||
* have been read.
|
||||
*
|
||||
* The response is a list of group range-value pair where:
|
||||
* - group range: The range of the group found where begin is the grouping
|
||||
* attribute handle and end is the handle of the end of the group.
|
||||
* - value: The value of the grouping attribute.
|
||||
*
|
||||
* This class has to be subclassed by an implementation specific class defining
|
||||
* the member function size and the subscript operator.
|
||||
*
|
||||
* @note The value responded can be trucated if it doesn't fit in the response,
|
||||
* in that case a Read Blob Request could be used to read the remaining octets.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.4.10
|
||||
*/
|
||||
struct AttReadByGroupTypeResponse : public AttServerMessage {
|
||||
/**
|
||||
* Data read from the grouping attribute.
|
||||
* It includes the range of the group and the value of the attribute.
|
||||
*/
|
||||
struct attribute_data_t {
|
||||
attribute_handle_range_t group_range;
|
||||
ArrayView<const uint8_t> value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base constructor, setup the OpCode of the response.
|
||||
*/
|
||||
AttReadByGroupTypeResponse() :
|
||||
AttServerMessage(AttributeOpcode::READ_BY_GROUP_TYPE_RESPONSE) {
|
||||
}
|
||||
|
||||
/**
|
||||
* virtual destructor to overide if the sub class needs it.
|
||||
*/
|
||||
virtual ~AttReadByGroupTypeResponse() { }
|
||||
|
||||
/**
|
||||
* Return the number of attribute_data_t present in the response.
|
||||
*/
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/**
|
||||
* Return the attribute data read at the index specified.
|
||||
* @note Out of range access is undefined.
|
||||
*/
|
||||
virtual attribute_data_t operator[](size_t index) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Write Response is sent in reply to a valid Write Request and
|
||||
* acknowledges that the attribute has been successfully written.
|
||||
* It is just a placeholder which indicates the client that the write request
|
||||
* was successful.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.5.2
|
||||
*/
|
||||
struct AttWriteResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct a write response.
|
||||
*/
|
||||
AttWriteResponse() : AttServerMessage(AttributeOpcode::WRITE_RESPONSE) { }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response to a Prepare Write Request. It acknowledges the client that the
|
||||
* value has been successfully received and placed in the write queue.
|
||||
*
|
||||
* The response contains the same values as the one present in the request.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.6.2
|
||||
*/
|
||||
struct AttPrepareWriteResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct a prepare write response.
|
||||
* @param handle_ The handle of the attribute to be written.
|
||||
* @param offset_: The offset of the first octet to be writen.
|
||||
* @param value_: The value of the attribute to be written at the offset
|
||||
* indicated.
|
||||
*/
|
||||
AttPrepareWriteResponse(
|
||||
attribute_handle_t handle_,
|
||||
uint16_t offset_,
|
||||
ArrayView<const uint8_t> value_
|
||||
) : AttServerMessage(AttributeOpcode::PREPARE_WRITE_RESPONSE),
|
||||
attribute_handle(handle_),
|
||||
offset(offset_),
|
||||
partial_value(value_) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The handle of the attribute to be written.
|
||||
*/
|
||||
const attribute_handle_t attribute_handle;
|
||||
|
||||
/**
|
||||
* The offset of the first octet to be writen.
|
||||
*/
|
||||
const uint16_t offset;
|
||||
|
||||
/**
|
||||
* The value of the attribute to be written at the offset indicated.
|
||||
*/
|
||||
const ArrayView<const uint8_t> partial_value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Execute Write Response is sent in response to a received Execute Write
|
||||
* Request.
|
||||
*
|
||||
* It is just a placeholder which indicates the client that the execution of the
|
||||
* write request has been successfull.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.6.4
|
||||
*/
|
||||
struct AttExecuteWriteResponse : public AttServerMessage {
|
||||
/**
|
||||
* Construct an execute write response object.
|
||||
*/
|
||||
AttExecuteWriteResponse() :
|
||||
AttServerMessage(AttributeOpcode::EXECUTE_WRITE_RESPONSE) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Notification of an attribute's value sent by the server.
|
||||
*
|
||||
* It contains the handle of the attribute and its value.
|
||||
*
|
||||
* If the attribute value is longer than (mtu - 3) then the value is truncated
|
||||
* to (mtu - 3) octets to fit in the response and the client will have to use
|
||||
* a read blob request to read the remaining octets of the attribute.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.7.1
|
||||
*/
|
||||
struct AttHandleValueNotification : public AttServerMessage {
|
||||
/**
|
||||
* Construct an Handle Value Notification from the attribute handle and its
|
||||
* value notified.
|
||||
*/
|
||||
AttHandleValueNotification(
|
||||
attribute_handle_t attribute_handle,
|
||||
ArrayView<const uint8_t> attribute_value
|
||||
) : AttServerMessage(AttributeOpcode::HANDLE_VALUE_NOTIFICATION),
|
||||
attribute_handle(attribute_handle),
|
||||
attribute_value(attribute_value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle of the attribute
|
||||
*/
|
||||
const attribute_handle_t attribute_handle;
|
||||
|
||||
/**
|
||||
* The current value of the attribute.
|
||||
*/
|
||||
const ArrayView<const uint8_t> attribute_value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Indication of an attribute's value sent by the server.
|
||||
*
|
||||
* It contains the handle of the attribute and its value. The client should
|
||||
* respond with and handle value confirmation.
|
||||
*
|
||||
* If the attribute value is longer than (mtu - 3) then the value is truncated
|
||||
* to (mtu - 3) octets to fit in the response and the client will have to use
|
||||
* a read blob request to read the remaining octets of the attribute.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.4.7.2
|
||||
*/
|
||||
struct AttHandleValueIndication : public AttServerMessage {
|
||||
/**
|
||||
* Construct an Handle Value Indication from the attribute handle and its
|
||||
* value indicated.
|
||||
*/
|
||||
AttHandleValueIndication(
|
||||
attribute_handle_t handle, ArrayView<const uint8_t> value
|
||||
) : AttServerMessage(AttributeOpcode::HANDLE_VALUE_INDICATION),
|
||||
attribute_handle(handle), attribute_value(value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle of the attribute
|
||||
*/
|
||||
const attribute_handle_t attribute_handle;
|
||||
|
||||
/**
|
||||
* The current value of the attribute.
|
||||
*/
|
||||
const ArrayView<const uint8_t> attribute_value;
|
||||
};
|
||||
|
||||
|
||||
} // namespace pal
|
||||
} // namespace ble
|
||||
|
||||
#endif /* BLE_PAL_ATT_SERVER_MESSAGE_H_ */
|
|
@ -0,0 +1,642 @@
|
|||
/* 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_GATT_CLIENT_H_
|
||||
#define BLE_PAL_GATT_CLIENT_H_
|
||||
|
||||
#include "ble/UUID.h"
|
||||
#include "ble/BLETypes.h"
|
||||
#include "ble/ArrayView.h"
|
||||
#include "ble/blecommon.h"
|
||||
|
||||
#include "platform/Callback.h"
|
||||
|
||||
#include "AttServerMessage.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
|
||||
/**
|
||||
* Adaptation layer for a GATT client.
|
||||
*
|
||||
* Define the primitive necessary to implement a proper GATT client. These
|
||||
* primitives are sometime GATT procedure, ATT procedure or a bit of both.
|
||||
*
|
||||
* In general, discovery procedures follow strictly GATT formulation while
|
||||
* attribute manipulation procedures (read/write) follow the ATT formulation
|
||||
* to avoid multiple identical implementation for characteristic values and
|
||||
* characteristic descriptors value, it also fill a hole leave by the
|
||||
* specification which doesn't define any GATT procedure to get the UUID of an
|
||||
* included service with a 128 bit UUID.
|
||||
*
|
||||
* Complementary informations around ATT procedures can be found in the Section
|
||||
* 3.4 of the Vol3, Part F of the Bluetooth specification while more informations
|
||||
* around the GATT procedures can be found in the Section 4 of the Vol 3, Part
|
||||
* G of the Bluetooth specification.
|
||||
*
|
||||
* Complete and compliant Gatt Client used by developer is realized at an higher
|
||||
* level using the primitives defined in this adaptation layer.
|
||||
*
|
||||
* If a stack expose the complete ATT layer then it is possible to provide an
|
||||
* implementation for GattClient by subclassing the AttClient class and use
|
||||
* the class AttClientToGattClientAdapter
|
||||
*/
|
||||
class GattClient {
|
||||
|
||||
public:
|
||||
/**
|
||||
* 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 usage 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;
|
||||
|
||||
/**
|
||||
* Negotiate the mtu to use by this connection.
|
||||
* First the client send to the server the maximum rx mtu that it can receive
|
||||
* then the client reply with the maximum rx mtu it can receive.
|
||||
* The mtu chosen for the connection is the minimum of the client Rx mtu
|
||||
* and server Rx mtu values.
|
||||
*
|
||||
* If an error occurred then the mtu used remains the default value.
|
||||
*
|
||||
* The server will reply to this request with an AttExchangeMTUResponse in
|
||||
* case of success or AttErrorResponse in case of failure.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.3.1
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t exchange_mtu(connection_handle_t connection) = 0;
|
||||
|
||||
/**
|
||||
* Acquire the size of the mtu for a given connection.
|
||||
*
|
||||
* @param connection The handle of the connection for which the the MTU size
|
||||
* should be acquired.
|
||||
*
|
||||
* @param mtu_size Output parameter which will contain the MTU size.
|
||||
*
|
||||
* @return BLE_ERROR_NONE if the MTU size has been acquired or the
|
||||
* appropriate error otherwise.
|
||||
*/
|
||||
virtual ble_error_t get_mtu_size(
|
||||
connection_handle_t connection_handle,
|
||||
uint16_t& mtu_size
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Discover primary services in the range [begin - 0xFFFF].
|
||||
*
|
||||
* If services exists in the range provided, the server will reply with a
|
||||
* ReadByGoupType response where for each attribute_data exposed:
|
||||
* - attribute_handle is the service attribute handle
|
||||
* - end_group_handle is the last handle of the service
|
||||
* - attribute_value is the UUID of the service.
|
||||
*
|
||||
* If the end of the range is not reached, this procedure can be relaunched
|
||||
* with the last handle of the last service discovered plus one as the
|
||||
* beginning of the discovery range.
|
||||
*
|
||||
* If there is not services left to discover in the range, the server can
|
||||
* either:
|
||||
* * Reply with an ErrorResponse with the Error code set to ATTRIBUTE_NOT_FOUND
|
||||
* * Set the end handle of the last service to 0xFFFF.
|
||||
*
|
||||
* @note This function realize a partial implementation of the Discover All
|
||||
* Primary Services procedure. The complete implementation of the procedure
|
||||
* is realized at an higher level.
|
||||
* @note This function issue a Read By Group Type ATT request where the
|
||||
* type parameter is equal to Primary Service and the Ending Handle parameter
|
||||
* is equal to 0xFFFF.
|
||||
* @note BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.4.1
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @param begin The beginning of the discovery range.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t discover_primary_service(
|
||||
connection_handle_t connection,
|
||||
attribute_handle_t discovery_range_begining
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Discover primary services by UUID in the range [discovery_range_begining - 0xFFFF].
|
||||
*
|
||||
* If services exists in the range provided, the server will reply with a
|
||||
* FindByTypeValueResponse containing the attribute range of each service
|
||||
* discovered.
|
||||
*
|
||||
* If the end of the range is not reached, this procedure can be relaunched
|
||||
* with the last handle of the last service discovered plus one as the
|
||||
* beginning of the discovery range.
|
||||
*
|
||||
* If there is not services left to discover in the range, the server can
|
||||
* either:
|
||||
* * Reply with an ErrorResponse with the Error code set to ATTRIBUTE_NOT_FOUND
|
||||
* * Set the end handle of the last service to 0xFFFF.
|
||||
*
|
||||
* @note This function realize a partial implementation of the Discover
|
||||
* Primary Service by Service UUID procedure. The complete implementation of
|
||||
* the procedure is realized at an higher level.
|
||||
* @note This function issue a Find By Type Value ATT request where the
|
||||
* type parameter is equal to Primary Service and the Ending Handle
|
||||
* parameter is equal to 0xFFFF.
|
||||
* @note BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.4.2
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @param begin The beginning of the discovery range.
|
||||
* @param uuid The UUID of the service to discover.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t discover_primary_service_by_service_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t discovery_range_beginning,
|
||||
const UUID& uuid
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Find included services within a service.
|
||||
*
|
||||
* If services are included in the service range then the server will reply
|
||||
* with a ReadByTypeResponse where for each attribute record:
|
||||
* - attribute_handle The handle where the service is included within the
|
||||
* service definition.
|
||||
* - attribute_data Contains two handles defining the range of the included.
|
||||
* If the service found have a 16 bit uuid then its UUID is also included
|
||||
* in the attribute data.
|
||||
*
|
||||
* If the end of the service range is not reached, this procedure can be
|
||||
* relaunched with the handle of the last included service discovered plus
|
||||
* one as the beginning of the new discovery range.
|
||||
*
|
||||
* The procedure is complete when either:
|
||||
* - The server reply with an ErrorResponse with the Error code set to
|
||||
* ATTRIBUTE_NOT_FOUND
|
||||
* - An included service handle returned is equal to the end of the range.
|
||||
*
|
||||
* If the service UUID is a 128 bits one then it is necessary to issue a read
|
||||
* attribute request on the first handle of the service discovered to get it.
|
||||
*
|
||||
* @note This function realize a partial implementation of the Find Included
|
||||
* Services procedure. The complete implementation of the procedure is
|
||||
* realized at an higher level.
|
||||
* @note This function issue a Read By Type ATT request where the
|
||||
* type parameter is equal to Include.
|
||||
* @note BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.5.1
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @param service_range The range of the service where service inclusion has
|
||||
* to be discovered.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t find_included_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t service_range
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Find characteristic declarations within a service definition.
|
||||
*
|
||||
* If characteristic declarations are found within the range then the server
|
||||
* should reply with a ReadByTypeResponse where for each attribute record:
|
||||
* - attribute_handle is the handle of the characteristic definition
|
||||
* - attribute_data contains the the following values attached to the
|
||||
* characteristic :
|
||||
* + properties: the properties of the characteristic.
|
||||
* + value handle: the handle of the value of the characteristic.
|
||||
* + uuid: the UUID of the characteristic.
|
||||
*
|
||||
* The procedure is considered complete when the server send an ErrorResponse
|
||||
* with the ErrorCode set to ATTRIBUTE_NOT_FOUND or a ReadByType response
|
||||
* has an attribute_handle set to the end of the discovery range.
|
||||
*
|
||||
* If the procedure is not complete after a server response, it should be
|
||||
* relaunched with an updated range starting at the last attribute_handle
|
||||
* discovered plus one.
|
||||
*
|
||||
* @note This function realize a partial implementation of the Discover All
|
||||
* Characteristics of a Service procedure. The complete implementation of
|
||||
* the procedure is realized at an higher level.
|
||||
* @note This function issue a Read By Type ATT request where the type
|
||||
* parameter is equal to Characteristic.
|
||||
* @note BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.6.1
|
||||
*
|
||||
* @note The GATT procedure Discover Characteristics by UUID is implemented
|
||||
* at a higher level using this function as a base.
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @param discovery_range The range of attributes where the characteristics
|
||||
* are discovered. It should be contained within a service.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t discover_characteristics_of_a_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Discover characteristic descriptors of a characteristic.
|
||||
*
|
||||
* If descriptors are found within the range provided then the server should
|
||||
* reply with a FindInformationResponse containing a list of
|
||||
* attribute_handle_t, UUID pairs where the attribute handle is the
|
||||
* descriptor handle and UUID is the UUID of the descriptor.
|
||||
*
|
||||
* The procedure is complete when the server send an ErrorResponse with the
|
||||
* error code ATTRIBUTE_NOT_FOUND or the FindInformationResponse has an
|
||||
* attribute handle that is equal to the end handle of the discovery range.
|
||||
*
|
||||
* @note This function realize a partial implementation of the Discover All
|
||||
* Characteristics Descriptors procedure. The complete implementation of
|
||||
* the procedure is realized at an higher level.
|
||||
* @note This function issue a Find Information ATT request..
|
||||
* @note BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.7.1
|
||||
*
|
||||
* @note It should be possible to use this function to issue a regular
|
||||
* ATT Find Information Request.
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @param descriptors_discovery_range The range of attributes where the
|
||||
* descriptors are discovered. The first handle shall be no less than the
|
||||
* characteristic value handle plus one and the last handle shall be no more
|
||||
* than the last handle of the characteristic.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t discover_characteristics_descriptors(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t descriptors_discovery_range
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Read the value of an attribute.
|
||||
*
|
||||
* The server will reply with an AttReadResponse. In case of error, the
|
||||
* server will reply with an AttErrorResponse.
|
||||
*
|
||||
* @note This function issue an ATT Read Request.
|
||||
*
|
||||
* @note: This function is the base function for the read Characteristic
|
||||
* Value and Read Characteristic Descriptor GATT procedures. It can also
|
||||
* be used to read the 128 bit UUID of a service discovered with
|
||||
* find_included_service.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.8.1
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.12.1
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @param attribute_handle Handle of the attribute to read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t read_attribute_value(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Read a characteristic value using its UUID (type).
|
||||
*
|
||||
* The server will respond a ReadByTypeResponse containing a sequence of
|
||||
* attribute handle and attribute value pairs.
|
||||
* To read remaining attributes, the client should launch a new request
|
||||
* with an updated range.
|
||||
*
|
||||
* The procedure is considered complete when the server respond with an
|
||||
* ErrorResponse containing the ErrorCode ATTRIBUTE_NOT_FOUND or when an
|
||||
* handle in the ReadByTypeResponse is equal to the end of the discovered
|
||||
* range.
|
||||
*
|
||||
* @note This function realize a partial implementation of the Read Using
|
||||
* Characteristics Characteristic procedure. The complete implementation of
|
||||
* the procedure is realized at an higher level.
|
||||
* @note This function issue a Read By Type ATT request.
|
||||
* @note BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.8.2
|
||||
*
|
||||
* @note It should be possible to use this function to issue a regular
|
||||
* ATT Read By Type Request.
|
||||
*
|
||||
* @param connection The handle of the connection to send this request to.
|
||||
* @param attribute_range Range of the handle where an attribute with
|
||||
* uuid as type is present.
|
||||
* @param uuid UUID of the characteristic(s) to read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t read_using_characteristic_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID& uuid
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Read a partial value of an attribute.
|
||||
*
|
||||
* The server will respond with a ReadBlobResponse containing the data read
|
||||
* or an ErrorResponse in case of error.
|
||||
*
|
||||
* The procedure is not complete as long as the value in response have the
|
||||
* same size as the mtu minus one. If the procedure is not complete, it can
|
||||
* be launch again with an updated offset to read the remaining part of the
|
||||
* attribute value.
|
||||
*
|
||||
* @note This function issue an ATT Read Blob Request.
|
||||
*
|
||||
* @note: This function is the base function for the Read Long
|
||||
* Characteristic Value and Read Long Characteristic Descriptor GATT
|
||||
* procedures.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.8.3
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.12.2
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this request to.
|
||||
* @param attribute_handle Handle of the attribute to read.
|
||||
* @param offset Beginning offset for the read operation.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t read_attribute_blob(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Read atomically multiple characteristics values.
|
||||
*
|
||||
* The server will respond with a ReadMultiple response containing the
|
||||
* concatenation of the values of the characteristics.
|
||||
*
|
||||
* @note values might be truncated
|
||||
*
|
||||
* In case of error, the server should respond a with an ErrorResponse.
|
||||
*
|
||||
* @note This function issue an ATT Read Multiple Request.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.8.4
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this request to.
|
||||
* @param characteristic_value_handles Handle of the characteristic values
|
||||
* to read.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t read_multiple_characteristic_values(
|
||||
connection_handle_t connection_handle,
|
||||
const ArrayView<const attribute_handle_t>& characteristic_value_handles
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a write command to the server.
|
||||
*
|
||||
* @note This function issue an ATT Write Command.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.9.1
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this request to.
|
||||
* @param attribute_handle Handle of the attribute to write.
|
||||
* @param value The value to write.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a Signed Write without Response command to the server.
|
||||
*
|
||||
* @note This function issue an ATT Write Command with the signed flag and
|
||||
* the signature.
|
||||
*
|
||||
* @note signature is calculated by the stack.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.9.2
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this request to.
|
||||
* @param attribute_handle Handle of the attribute to write.
|
||||
* @param value The value to write.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t signed_write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a write request to the server.
|
||||
*
|
||||
* The server should respond with a WriteResponse in case of success or an
|
||||
* ErrorResponse in case of error.
|
||||
*
|
||||
* @note This function issue an ATT Write Request.
|
||||
*
|
||||
* @note: This function is the base function for the Write Characteristic
|
||||
* Value and Write Characteristic Descriptors GATT procedures.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.9.3
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.12.3
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this request to.
|
||||
* @param attribute_handle Handle of the attribute to write.
|
||||
* @param value The value to write.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t write_attribute(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a prepare write request to the server.
|
||||
*
|
||||
* The write request will go into a queue until the client execute or cancel
|
||||
* the request with an execute write request which will write all the values
|
||||
* in the queue atomically.
|
||||
*
|
||||
* The server should respond with a PrepareWriteResponse containing the
|
||||
* content of the request in case of success and an ErrorResponse in case of
|
||||
* error.
|
||||
*
|
||||
* If an ErrorResponse is received it doesn't invalidate what is already in
|
||||
* the queue.
|
||||
*
|
||||
* @note This function issue an ATT Prepare Write Request.
|
||||
*
|
||||
* @note: This function is one of the base function for the Write Long
|
||||
* Characteristic Value and Reliable Writes GATT procedures.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.9.4
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.9.5
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this request to.
|
||||
* @param attribute_handle Handle of the attribute to write.
|
||||
* @param value The value to write.
|
||||
* @param offset offset where the value should be written.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t queue_prepare_write(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value,
|
||||
uint16_t offset
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Send a request to the server to execute the queue of prepared write
|
||||
* requests.
|
||||
*
|
||||
* The server should respond with an ExecuteWriteResponse in case of success
|
||||
* and an Error response in case of failure.
|
||||
*
|
||||
* @note This function issue an ATT Execute Write Request.
|
||||
*
|
||||
* @note: This function is one of the base function for the Write Long
|
||||
* Characteristic Value and Reliable Writes GATT procedures.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.9.4
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.9.5
|
||||
*
|
||||
* @param connection_handle The handle of the connection to send this request to.
|
||||
* @param execute If true, execute the write request queue otherwise cancel it.
|
||||
*
|
||||
* @return BLE_ERROR_NONE or an appropriate error.
|
||||
*/
|
||||
virtual ble_error_t execute_write_queue(
|
||||
connection_handle_t connection_handle,
|
||||
bool execute
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Register a callback which will handle messages from the server.
|
||||
*
|
||||
* @param cb The callback object which will handle messages from the server.
|
||||
* It accept two parameters in input: The handle of the connection where the
|
||||
* message was received and the message received. Real type of the message
|
||||
* can be obtained from its opcode.
|
||||
*/
|
||||
void when_server_message_received(
|
||||
mbed::Callback<void(connection_handle_t, const AttServerMessage&)> cb
|
||||
) {
|
||||
_server_message_cb = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback handling transaction timeout.
|
||||
*
|
||||
* @param cb The callback handling timeout of a transaction. It accepts as
|
||||
* a parameter the connection handle involved in the timeout.
|
||||
*
|
||||
* @note No more attribute protocol requests, commands, indication or
|
||||
* notification shall be sent over a connection implied in a transaction
|
||||
* timeout. To send a new ATT message, the conenction should be
|
||||
* reestablished.
|
||||
*/
|
||||
void when_transaction_timeout(
|
||||
mbed::Callback<void(connection_handle_t)> cb
|
||||
) {
|
||||
_transaction_timeout_cb = cb;
|
||||
}
|
||||
|
||||
protected:
|
||||
GattClient() { }
|
||||
|
||||
virtual ~GattClient() { }
|
||||
|
||||
/**
|
||||
* Upon server message reception an implementation shall call this function.
|
||||
*
|
||||
* @param connection_handle The handle of the connection which has received
|
||||
* the server message.
|
||||
* @param server_message The message received from the server.
|
||||
*/
|
||||
void on_server_event(
|
||||
connection_handle_t connection_handle,
|
||||
const AttServerMessage& server_message
|
||||
) {
|
||||
if (_server_message_cb) {
|
||||
_server_message_cb(connection_handle, server_message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upon transaction timeout an implementation shall call this function.
|
||||
*
|
||||
* @param connection_handle The handle of the connection of the transaction
|
||||
* which has times out.
|
||||
*
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part F Section 3.3.3
|
||||
* @note see BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G Section 4.4.14
|
||||
*/
|
||||
void on_transaction_timeout(
|
||||
connection_handle_t connection_handle
|
||||
) {
|
||||
if (_transaction_timeout_cb) {
|
||||
_transaction_timeout_cb(connection_handle);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Callback called when the client receive a message from the server.
|
||||
*/
|
||||
mbed::Callback<void(connection_handle_t, const AttServerMessage&)> _server_message_cb;
|
||||
|
||||
/**
|
||||
* Callback called when a transaction times out.
|
||||
*/
|
||||
mbed::Callback<void(connection_handle_t)> _transaction_timeout_cb;
|
||||
|
||||
// Disallow copy construction and copy assignment.
|
||||
GattClient(const GattClient&);
|
||||
GattClient& operator=(const GattClient&);
|
||||
};
|
||||
|
||||
} // namespace pal
|
||||
} // namespace ble
|
||||
|
||||
#endif /* BLE_PAL_GATT_CLIENT_H_ */
|
|
@ -0,0 +1,232 @@
|
|||
/* 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_SIMPLEATTSERVERMESSAGE_H_
|
||||
#define BLE_PAL_SIMPLEATTSERVERMESSAGE_H_
|
||||
|
||||
#include "AttServerMessage.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
|
||||
/**
|
||||
* Simple implementation of ble::pal::AttFindInformationResponse.
|
||||
* It should fit for any vendor stack exposing a proper ATT interface.
|
||||
*/
|
||||
struct SimpleAttFindInformationResponse : public AttFindInformationResponse {
|
||||
/**
|
||||
* Format of the UUID in the response.
|
||||
*/
|
||||
enum Format {
|
||||
FORMAT_16_BIT_UUID = 0x01,//!< FORMAT_16_BIT_UUID
|
||||
FORMAT_128_BIT_UUID = 0x02//!< FORMAT_128_BIT_UUID
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an AttFindInformationResponse from format and an array of bytes
|
||||
* containing the information data.
|
||||
* @param format The format of the information data.
|
||||
* @param information_data The information data whose format is determined
|
||||
* by the Format field
|
||||
*/
|
||||
SimpleAttFindInformationResponse(
|
||||
Format format, ArrayView<const uint8_t> information_data
|
||||
) : AttFindInformationResponse(),
|
||||
_format(format), _information_data(information_data),
|
||||
_item_size(information_data_item_size()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttFindInformationResponse::size
|
||||
*/
|
||||
virtual size_t size() const {
|
||||
return _information_data.size() / _item_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttFindInformationResponse::operator[]
|
||||
*/
|
||||
virtual information_data_t operator[](size_t index) const {
|
||||
const uint8_t* item = &_information_data[index * _item_size];
|
||||
|
||||
information_data_t result;
|
||||
memcpy(&result.handle, item, sizeof(result.handle));
|
||||
|
||||
if (_format == FORMAT_16_BIT_UUID) {
|
||||
uint16_t short_uuid = 0;
|
||||
memcpy(&short_uuid, item + 2, sizeof(short_uuid));
|
||||
result.uuid = UUID(short_uuid);
|
||||
} else {
|
||||
result.uuid = UUID(item + 2, UUID::LSB);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t information_data_item_size() const {
|
||||
return sizeof(attribute_handle_t) + ((_format == FORMAT_16_BIT_UUID) ? 2 : 16);
|
||||
}
|
||||
|
||||
const Format _format;
|
||||
const ArrayView<const uint8_t> _information_data;
|
||||
const size_t _item_size;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of ble::pal::AttFindByTypeValueResponse.
|
||||
* It should fit for any vendor stack exposing a proper ATT interface.
|
||||
*/
|
||||
struct SimpleAttFindByTypeValueResponse : public AttFindByTypeValueResponse {
|
||||
/**
|
||||
* Construct a AttFindByTypeValueResponse from a raw array containing the
|
||||
* Handle Informations.
|
||||
* @param handles raw array containing one or more Handle Informations.
|
||||
*/
|
||||
SimpleAttFindByTypeValueResponse(ArrayView<const uint8_t> handles) :
|
||||
AttFindByTypeValueResponse(), _handles(handles) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttFindByTypeValueResponse::size
|
||||
*/
|
||||
virtual std::size_t size() const {
|
||||
return _handles.size() / item_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttFindByTypeValueResponse::operator[]
|
||||
*/
|
||||
virtual attribute_handle_range_t operator[](size_t index) const {
|
||||
attribute_handle_range_t result;
|
||||
const uint8_t* item = &_handles[index * item_size];
|
||||
memcpy(&result.begin, item, sizeof(result.begin));
|
||||
memcpy(&result.end, item + sizeof(result.begin), sizeof(result.end));
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t item_size = 4;
|
||||
const ArrayView<const uint8_t> _handles;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of ble::pal::AttReadByTypeResponse.
|
||||
* It should fit for any vendor stack exposing a proper ATT interface.
|
||||
*/
|
||||
struct SimpleAttReadByTypeResponse : public AttReadByTypeResponse {
|
||||
/**
|
||||
* Construct an AttReadByTypeResponse from the size of each attribute
|
||||
* handle-value pair and a list of attribute data.
|
||||
* @param element_size The size of each attribute-handle pair.
|
||||
* @param attribute_data Raw bytes array containing the list of attribute
|
||||
* data.
|
||||
*/
|
||||
SimpleAttReadByTypeResponse(
|
||||
uint8_t element_size, ArrayView<const uint8_t> attribute_data
|
||||
) : AttReadByTypeResponse(),
|
||||
_attribute_data(attribute_data), _element_size(element_size) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttReadByTypeResponse::size
|
||||
*/
|
||||
virtual size_t size() const {
|
||||
return _attribute_data.size() / _element_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttReadByTypeResponse::operator[]
|
||||
*/
|
||||
virtual attribute_data_t operator[](size_t index) const {
|
||||
const uint8_t* item = &_attribute_data[index * _element_size];
|
||||
uint16_t handle;
|
||||
memcpy(&handle, item, sizeof(handle));
|
||||
|
||||
attribute_data_t result = {
|
||||
handle,
|
||||
ArrayView<const uint8_t>(
|
||||
item + sizeof(handle),
|
||||
_element_size - sizeof(handle)
|
||||
)
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
ArrayView<const uint8_t> _attribute_data;
|
||||
uint8_t _element_size;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of ble::pal::AttReadByGroupTypeResponse.
|
||||
* It should fit for any vendor stack exposing a proper ATT interface.
|
||||
*/
|
||||
struct SimpleAttReadByGroupTypeResponse : public AttReadByGroupTypeResponse {
|
||||
/**
|
||||
* Construct an instance of AttReadByGroupTypeResponse from the size of each
|
||||
* attribute data and a byte array containing the list of attribute data.
|
||||
* @param element_size The size of each Attribute Data
|
||||
* @param attribute_data Byte array containing the list of Attribute Data.
|
||||
*/
|
||||
SimpleAttReadByGroupTypeResponse(
|
||||
uint8_t element_size, ArrayView<const uint8_t> attribute_data
|
||||
) : AttReadByGroupTypeResponse(),
|
||||
_attribute_data(attribute_data), _element_size(element_size) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttReadByGroupTypeResponse::size
|
||||
*/
|
||||
virtual size_t size() const {
|
||||
return _attribute_data.size() / _element_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ble::pal::AttReadByGroupTypeResponse::operator[]
|
||||
*/
|
||||
virtual attribute_data_t operator[](size_t index) const {
|
||||
const uint8_t* item = &_attribute_data[index * _element_size];
|
||||
uint16_t begin;
|
||||
uint16_t end;
|
||||
|
||||
memcpy(&begin, item, sizeof(begin));
|
||||
memcpy(&end, item + sizeof(begin), sizeof(end));
|
||||
|
||||
attribute_data_t result = {
|
||||
{ begin, end },
|
||||
ArrayView<const uint8_t>(
|
||||
item + sizeof(begin) + sizeof(end),
|
||||
_element_size - (sizeof(begin) + sizeof(end))
|
||||
)
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
ArrayView<const uint8_t> _attribute_data;
|
||||
uint8_t _element_size;
|
||||
};
|
||||
|
||||
} // namespace pal
|
||||
} // namespace ble
|
||||
|
||||
#endif /* BLE_PAL_SIMPLEATTSERVERMESSAGE_H_ */
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue