mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
Diff: features/FEATURE_BLE/ble/pal/AttClient.h
- Revision:
- 0:5b88d5760320
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/features/FEATURE_BLE/ble/pal/AttClient.h Tue Dec 17 23:23:45 2019 +0000 @@ -0,0 +1,737 @@ +/* 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/common/StaticInterface.h" +#include "ble/UUID.h" +#include "ble/BLETypes.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 + */ +template<class Impl> +struct AttClient : public StaticInterface<Impl, AttClient> { +private: + + using StaticInterface<Impl, ble::pal::AttClient>::impl; + +public: + + + /** + * 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. + */ + ble_error_t initialize() { + return impl()->initialize_(); + } + + /** + * 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. + */ + ble_error_t terminate() { + return impl()->terminate_(); + } + + /** + * 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 + */ + ble_error_t exchange_mtu_request(connection_handle_t connection) { + return impl()->exchange_mtu_request_(connection); + } + + /** + * 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. + */ + ble_error_t get_mtu_size( + connection_handle_t connection_handle, + uint16_t& mtu_size + ) { + return impl()->get_mtu_size_(connection_handle, mtu_size); + } + + /** + * 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 + */ + ble_error_t find_information_request( + connection_handle_t connection_handle, + attribute_handle_range_t discovery_range + ) { + return impl()->find_information_request_(connection_handle, discovery_range); + } + + /** + * 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 + */ + ble_error_t find_by_type_value_request( + connection_handle_t connection_handle, + attribute_handle_range_t discovery_range, + uint16_t type, + const Span<const uint8_t>& value + ) { + return impl()->find_by_type_value_request_( + connection_handle, + discovery_range, + type, + value + ); + } + + /** + * 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 + */ + ble_error_t read_by_type_request( + connection_handle_t connection_handle, + attribute_handle_range_t read_range, + const UUID& type + ) { + return impl()->read_by_type_request_(connection_handle, read_range, type); + } + + /** + * 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 + */ + ble_error_t read_request( + connection_handle_t connection_handle, + attribute_handle_t attribute_handle + ) { + return impl()->read_request_(connection_handle, attribute_handle); + } + + /** + * 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 + */ + ble_error_t read_blob_request( + connection_handle_t connection_handle, + attribute_handle_t attribute_handle, + uint16_t offset + ) { + return impl()->read_blob_request_(connection_handle, attribute_handle, offset); + } + + /** + * 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 + */ + ble_error_t read_multiple_request( + connection_handle_t connection_handle, + const Span<const attribute_handle_t>& attribute_handles + ) { + return impl()->read_multiple_request_(connection_handle, attribute_handles); + } + + /** + * 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 + */ + ble_error_t read_by_group_type_request( + connection_handle_t connection_handle, + attribute_handle_range_t read_range, + const UUID& group_type + ) { + return impl()->read_by_group_type_request_(connection_handle, read_range, group_type); + } + + /** + * 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 + */ + ble_error_t write_request( + connection_handle_t connection_handle, + attribute_handle_t attribute_handle, + const Span<const uint8_t>& value + ) { + return impl()->write_request_(connection_handle, attribute_handle, value); + } + + /** + * 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 + */ + ble_error_t write_command( + connection_handle_t connection_handle, + attribute_handle_t attribute_handle, + const Span<const uint8_t>& value + ) { + return impl()->write_command_(connection_handle, attribute_handle, value); + } + + /** + * 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 + */ + ble_error_t signed_write_command( + connection_handle_t connection_handle, + attribute_handle_t attribute_handle, + const Span<const uint8_t>& value + ) { + return impl()->signed_write_command_(connection_handle, attribute_handle, value); + } + + /** + * 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 + * + */ + ble_error_t prepare_write_request( + connection_handle_t connection_handle, + attribute_handle_t attribute_handle, + uint16_t offset, + const Span<const uint8_t>& value + ) { + return impl()->prepare_write_request_( + connection_handle, + attribute_handle, + offset, + value + ); + } + + /** + * 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 + */ + ble_error_t execute_write_request( + connection_handle_t connection_handle, + bool execute + ) { + return impl()->execute_write_request_(connection_handle, execute); + } + + /** + * 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() { } + + ~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_ */