mbed-os/features/FEATURE_BLE/ble/pal/PalGattClient.h

643 lines
26 KiB
C++

/* 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_ */